977.有序数组的平方
要点
- 给定一个非递减的数组,两头是平方大的数字,设置头尾两个相向的指针,选大的元素从后往前放在
result数组中
双指针法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> tmp(nums.size());
int left = 0;
int right = nums.size()-1;
for (int i = nums.size()-1; i>=0; i--){
if (nums[left]*nums[left] < nums[right]*nums[right]){
tmp[i] = nums[right] * nums[right];
right--;
}else{
tmp[i] = nums[left] * nums[left];
left++;
}
}
return tmp;
}
};
总结
在for循环内部,每轮都会有++或--的操作,在nums.size()轮内会安排完所有的元素,不用循环判断条件left<=right
209.长度最小的子数组
滑动窗口法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0;
int slow = 0;
int minlen = nums.size()+1;
for (int fast = 0; fast < nums.size(); fast++){//移动前面指针
sum += nums[fast];
while (sum >= target){//缩slow指针,是while,不是if
minlen = minlen < (fast-slow+1) ? minlen : (fast-slow+1);//满足条件的子数组记录
sum -= nums[slow];
slow++;
}
}
return minlen == (nums.size()+1) ? 0 : minlen;
}
};
要点
minlen初始值需要一个大于数组长度的值-
- 更新
minlen是选择较小的子数组长度,故初始值需要很大
- 更新
-
- 因为数组长度也可能是解,而无子数组应返回0,故初始值不能设为
nums.size()
- 因为数组长度也可能是解,而无子数组应返回0,故初始值不能设为
-
- 简单的
if判断,如a = min(a, b)更新操作,可以用三目运算符? :代替 - 滑动窗口实现时,前后两个指针都是往一个方向,不回头的移动
总结
两个指针移动,fast指针先移动,slow根据条件再移动,fast指针的移动写在for循环里,slow指针满足while条件再移动。fast移动只有大于等于target才停止,slow移动只有sum < target了才停止。
59.螺旋矩阵II
模拟螺旋的过程
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int startx = 0; int starty = 0;
int offset = 1;
int loop = n/2;
int i, j;
int count = 1;
while (loop--){ //每轮完成一圈的赋值
i = startx;
j = starty;
for (j = starty; j < n-offset; j++){ //依次顺时针行列赋值
res[startx][j] = count++;
}
for (i = startx; i < n-offset; i++){
res[i][j] = count++;
}
for (; j > starty; j--){
res[i][j] = count++;
}
for (; i > startx; i--){
res[i][j] = count++;
}
startx++; starty++; offset++;
}
if (n%2 == 1){
res[n/2][n/2] = count;
}
return res;
}
};
要点
- 每轮中的
i,j为模拟螺旋的变量,startx, starty, offset为每轮变化,但轮内不变化的参数 - 每轮需要注意:起始的坐标、
for循环的左闭右开边界、i,j的移动轨迹 i, j为有实际意义的变量,不要初始化在for循环内作临时变量
总结
螺旋矩阵作为模拟题,想清楚每轮的赋值顺序和边界控制,代码还是挺清晰的。
数组章 总结
- 二分法
- 双指针
- 滑动窗口
- 模拟
重点是双指针的用法,双指针可以有删除元素中的同向的快慢指针,也有元素平方的相向的双指针,使用须灵活。 滑动窗口也是一种特殊的同向双指针。