内容:
有序数组的平方(977)
长度最小的子数组(209)
螺旋矩阵II(59)
数组总结
1.有序数组的平方
1.1 思路分析
开始的思路为先平方得到一个数组然后进行排序。但很显然这种方法的时间复杂度较高。
看完题解后我学到了使用双指针来解决问题,通过比较两端的值来获得较大的赋给新的数组的靠后的元素。
如图所示:
1.2 代码实现
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
int k = nums.length - 1;
int[] result = new int[nums.length];
while (left <= right){
if (nums[left] * nums[left] < nums[right] * nums[right]){
result[k--] = nums[right] * nums[right];
right--;
}else{
result[k--] = nums[left] * nums[left];
left++;
}
}
return result;
}
}
1.3注意事项
- 循环继续的left 与right的判断条件为 <=,否则会漏值****
- 将较大的值赋给新的数组而不是题目给的数组
2.长度最小的子数组
2.1 思路分析
一开始我的思路是很复杂混乱的,想要通过一个变量 i 记录起始位置,另一个变量遍历数组然后 i++,继续遍历;
实际上这题通过滑动窗口的方式是很巧妙的,所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。
如图所示:
2.2 代码实现
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//滑动窗口
int sum = 0;//记录数的和
int minValue = Integer.MAX_VALUE;//记录长度
int left = 0;
for(int right = 0;right < nums.length;right++){
sum += nums[right];
while (sum >= target){
minValue = Math.min(minValue,right - left + 1);
sum -= nums[left++];
}
}
return minValue == Integer.MAX_VALUE ? 0 : minValue;
}
}
2.3 注意事项
-
窗口内是什么?
- 窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组
-
如何移动窗口的起始位置?
- 窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)
-
如何移动窗口的结束位置?
- 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引
-
解题的关键在于窗口的起始位置如何移动
-
while循环实现了right不变而left改变的情形
-
right 指向终止位置
3.螺旋矩阵
3.1 思路分析
写的时候基本没有什么思路,觉得各种条件难以处理。
看完解答后知道了首先要确定边界的范围是左闭右开还是左开右闭,在while循环中
- 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左列从下到上
由外向内不断递进。如图:
3.2 代码实现
class Solution {
public int[][] generateMatrix(int n) {
int nums[][] = new int[n][n];
int loop = n / 2;//记录循环的次数
int offset = 1;//每进行一次循环需要减掉的值
int startx = 0;
int starty = 0;
int count = 1;
int mid = n / 2;//中间值的索引
while (loop != 0){
int i = startx;
int j = starty;
for (j = starty;j < n - offset;j++){
nums[i][j] = count++;
}
for(i = startx;i < n - offset;i++){
nums[i][j] = count++;
}
for(;j > starty;j--){
nums[i][j] = count++;
}
for(;i > startx;i--){
nums[i][j] = count++;
}
startx++;//向内循环,起始位置要+1
starty++;//同上理
offset++;//循环次数减少
loop--;//进行一次减少一次循环
}
if (n % 2 == 1){//判断是否为奇数,如果是奇数则将count 赋给中间的值nums[mid][mid]
nums[mid][mid] = count;
}
return nums;
}
}
3…3 注意事项
- 坚持循环不变量原则
- 每一圈的起始点不相同,所以需要起始位置个要加1
- 理清边界条件的定义是问题解决的关键
4.数组总结
- 二分法,双指针法,滑动窗口,模拟行为是这章我们需要掌握的知识点与思想
- 循环不变量原则是写程序的重要原则
总结图片:来自代码随想录知识星球成员:海螺人