代码随想录Day02 数组基础2 leetcode T977有序数组的平方, T209 长度最小的子数组,T59 螺旋矩阵II

news/2024/12/22 21:12:49/

本文思路和详细解答来源于:

代码随想录

视频讲解见:

双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

Leetcode T977 有序数组的平方

题目链接:

977. 有序数组的平方 - 力扣(LeetCode)

思路1: 暴力求解

这里先解释一下非递减顺序:

1223445

非递增顺序:

5443221

首先我们可以使用暴力求解,直接创建一个新数组,将原数组的元素平方放入新数组,再将新数组使用快排,就完成了.

时间复杂度:O(nlogn)

class Solution {
public:vector<int> sortedSquares(vector<int>& A) {for (int i = 0; i < A.size(); i++) {A[i] *= A[i];}sort(A.begin(), A.end()); // 快速排序return A;}
};

思路2: 双指针写法 

我们发现,平方之后较大的数一定在两边,所以,我们可以创建两个指针,一个指针指向最后一个元素,一个指针指向首元素,两个指针向中间移动,这时候,由于只能先获得较大的数,我们用一个指针指向新创建的数组的最后一个元素,从后向前更新新数组.

class Solution {public int[] sortedSquares(int[] nums) {int size = nums.length - 1;int i,j;int k = size;int[] result = new int [size + 1];for(i = 0,j = size;i<=j;){if(nums[i]*nums[i] < nums[j]*nums[j]){result[k] = nums[j] * nums[j];k--;j--;}else{result[k] = nums[i] * nums[i];k--;i++;}}return result;}
}

这里我们 就用O(n)的时间复杂度解决了问题,仅仅遍历了一次数组,效率还是提升了不少的.

总结:

当出现有序数组的时候,我们可以考虑双指针的解法 

Leetcode T209 长度最小的子数组

题目链接:209. 长度最小的子数组 - 力扣(LeetCode)

 

思路1: 暴力求解(现在跑不过)

这个时候我们很容易想到用两层for循环遍历两次数组,显然代码的时间复杂度是O(n^2),我们只需要给定一个sum记录子区间的总和,subLength记录总区间的长度,两个变量ij记录子序列的起始位置和终止位置,在开始的时候定义一个result作为返回值.

class Solution {public int minSubArrayLen(int target, int[] nums) {int result = Integer.MAX_VALUE;int i = 0;//开始位置int j = 0;//结束为止int sum = 0;for(i = 0;i<nums.length;i++){sum = 0;for(j = i;j<nums.length;j++){//遍历i到最后sum += nums[j];if(sum >= target){//取子序列的长度subLength = j-i+1;//找到长度最小的序列result = result < subLength ? result : subLength;break;}}}//如果result没变就是没有适合的元素的序列return result == Integer.MAX_VALUE? 0: result;}
}

总结

算法的总思路是第一次寻找起始位置,第二个for循环是寻找结束位置,从i开始累加,一旦累加的结果大于target就跳出,就说明从此时的i开始寻找到了满足条件的子序列,然后继续遍历以此类推.

思路2:滑动窗口 

总体思想就是不断调整起始位置和终止位置,从而达到我们想要的效果

暴力解法是通过一个for循环是滑动窗口的起始位置,一个for循环是滑动窗口的结束位置,从而达到搜索整个数组的效果.

那么我们这个滑动窗口如何使用一个for循环来解决问题呢?

如果我们使用一个for循环代替起始位置,那难免会又想到暴力解法的思路上去,

所以这个for循环一定代表的是滑动窗口的末尾位置

举例说明:假设target的值是7,我们在 2 3 1 2 4 3这个数组里求最小的子数组

首先我们找到大于等于7的连续子数组 2 3 1 2,   条件:累计和>=7

这个时候我们的窗口就应该缩小了

3 1 2是不满足的,所以我们继续向后找

3 1 2 4满足条件,缩小

1 2 4满足条件,缩小

2 4不满足条件 ,向前走

2 4 3满足条件,缩小

3 4 ,找到答案,返回2

注:图片取自于代码随想录网站,可以在文首点击查看详细解答. 

解答代码: 

class Solution {public int minSubArrayLen(int target, int[] nums) {//滑动窗口int result = Integer.MAX_VALUE;int i = 0;//左指针int sum = 0;for(int j = 0;j<nums.length;j++){sum += nums[j];while(sum >= target){result = Math.min(result,j-i + 1);sum -= nums[i++];}}return result == Integer.MAX_VALUE?0:result;}
}

注:不一定循环中套用循环就是O(n^2)的时间复杂度,这里是O(n*2)的时间复杂度也就是O(n)的时间复杂度,具体是么时候是O(n*n)什么时候是O(n+n).

这里我们可以看到暴力求解的时候两层都对i操作,也就是元素被操作了n*n次,就是O(n^2)的时间复杂度,这里是 在进窗口操作一次出窗口操作n次,所以是O(n)的时间复杂度.

总结:第一次做滑动窗口的问题,我认为更重要的是掌握这种让窗口动起来的同时不断更新子序列大小和位置的思想.

Leetcode T59 螺旋矩阵II

 提示:1 <= n <= 20

思路: 

题目的关键是保证循环变量中的不变量,我们的目的是用一个二维数组模拟实现这个矩阵,

定义一个起始坐标(start,start),我们定义一个while循环,循环次数是n/2次,那么有同学就会问了,我万一n是奇数怎么办,奇数的话我们的n就可以另外处理,定义一个loop,来控制每次执行完一圈我们向里进一圈.

重点:循环不变量的确定,这里我们一定要搞清楚每一次写入的区间,是左开右闭还是闭区间,这样才能保证代码的书写稳中不乱,这里我们选择的区间的左闭右开区间.

int start = 0;
int count = 1;
int loop = n/2;
int i,j;

解答代码: 

class Solution {public int[][] generateMatrix(int n) {int[][] arr = new int[n][n];//起始地址int start = 0;//计数器int count = 1;//用来控制循环int loop = 0;//用来解决n等于奇数的问题int mid = n/2;int i,j;while(loop++<mid) {//顺时针填入填入矩阵元素for(j = start;j<n-loop;j++) {arr[start][j] = count++;}for(i = start;i<n-loop;i++){arr[i][j] = count++;}for(;j>=loop;j--){arr[i][j] = count++;}for(;i>=loop;i--){arr[i][j] = count++;}start++;}if(n%2 == 1){arr[mid][mid] = count;}return arr;}}

 总结:

在遇到有序数组时,可以考虑二分法

一定要牢记循环不变量原则,找准循环中的不变量

找一个连续的子数组的总和值,可以想到滑动窗口解决问题


http://www.ppmy.cn/news/1122986.html

相关文章

008_第一代软件系统架构

第一代软件系统架构 文章目录 第一代软件系统架构项目介绍软件架构和软件构架系统框架硬件组成运行系统基础库软件层 系统架构 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&…

LCR 157. 套餐内商品的排列顺序

LCR 157. 套餐内商品的排列顺序 某店铺将用于组成套餐的商品记作字符串 goods&#xff0c;其中 goods[i] 表示对应商品。请返回该套餐内所含商品的 全部排列方式 。 返回结果 无顺序要求&#xff0c;但不能含有重复的元素。 示例 1: 输入&#xff1a;goods “agew” 输出&…

玩玩“小藤”开发者套件 Atlas 200I DK A2 之VSCode远程连接

玩玩“小藤”开发者套件 Atlas 200I DK A2 之VSCode远程连接 0. 背景1. VSCode 安装 Remote - SSH 插件2. 安装 OpenSSH 组件3. VSCode SSH 连接 Atlas 200I DK A24. 打开远程文件夹 0. 背景 总所周知&#xff0c;英伟达的GPU供不应求&#xff0c;还各种限制。华为推出了升腾A…

Quartus出租车计价器VHDL计费器

名称&#xff1a;出租车计价器VHDL计费器 软件&#xff1a;Quartus 语言&#xff1a;VHDL 要求&#xff1a; 启动键start表示汽车启动&#xff0c;起步价7元&#xff0c;同时路程开始计数&#xff0c;停止键stop表示熄火&#xff0c;车费和路程均为0&#xff0c;当暂停键pa…

JavaScript系列从入门到精通系列第六篇:JavaScrip当中的运算符,主要涉及JavaScript当中的六大数据类型的四则运算

文章目录 前言 一&#xff1a;算数运算符 1&#xff1a;Number类型的四则运算 2&#xff1a;其他数据类型的四则运算 (一)&#xff1a;加法运算 (二)&#xff1a;减法运算 3&#xff1a;乘法运算 4&#xff1a;除法运算 5&#xff1a;取模运算 前言 运算符也叫操作符。…

vscode调试webpack项目的方法

vscode调试webpack项目的方法 首先安装vscode插件Javascript Debugger 这个插件的介绍也写清楚了&#xff1a; An extension for debugging Node.js programs and Chrome. 那就是用来调试Node.js和Chrome的vscode扩展插件&#xff0c;包括typescript. 然后按F5启动调试&…

(GD32单片机写入程序后无反应)GD32单片机内外部晶振切换

以GD32F405RG系列为例&#xff0c;43到54行是库函数提供的内外晶振宏定义。 尾部为IRC的是内部晶振&#xff0c;尾部为HXTAL的是外部晶振。43~54当中只能选择一项作为晶振设置&#xff0c;其他项必须注释掉。 例如我选择的是以IRC结尾的49行&#xff0c;意思是使用GD32的内部晶…

OSI 七层网络协议最全的图

OSI 七层网络协议最全的图 文章出处&#xff1a;https://www.shuzhiduo.com/A/RnJWawowdq/