代码随想录算法训练营二刷day2| 977. 有序数组的平方、209. 长度最小的子数组、59.螺旋矩阵 II
LeetCode 977题 有序数组的平方
题目链接: 977.有序数组的平方
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> arr(nums.size(), 0); //根据原数组大小创建新数组
int j = nums.size() - 1; //指向新数组末尾
for(int i = 0, k = nums.size() - 1; i <= k;) { //创建首、尾双指针
if(nums[i] * nums[i] > nums[k] * nums[k]) {
arr[j--] = nums[i] * nums[i];
i++;
}
else {
arr[j--] = nums[k] * nums[k];
k--;
}
}
return arr;
}
};
本题小结:题目要求时间复杂度为O(n),暴力法行不通,因为数组本身有序排列,那么平方之后的最大值一定出在数组最左边或者最右边,那么新建数组,通过反向双指针进行比较放入新数组即可。
LeetCode 209题 长度最小的子数组
题目链接: 209.长度最小的子数组
滑动窗口法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int res = INT32_MAX;
int subLength = 0;
int sum = 0;
int i = 0;
for(int j = 0; j < nums.size(); j++) {
sum += nums[j];
while(sum >= target) {
subLength = j - i + 1;
res = res < subLength ? res : subLength;
sum -= nums[i++]; //这一步是滑动窗口"滑动"的关键!
}
}
return res == INT32_MAX ? 0 : res;
}
};
本题小结:滑动窗口法的核心代码
while(sum >= target) {
subLength = j - i + 1;
res = res < subLength ? res : subLength;
sum -= nums[i++]; //这一步是关键
}
LeetCode 59题 螺旋矩阵 II
题目链接: 35.螺旋矩阵 II
class Solution {
public:
vector<vector<int> > generateMatrix(int n) {
vector<vector<int> > res(n , vector<int>(n, 0)); //初始化数组
int loop = n / 2; //首先确定循环圈的大小
int i, j; //定义数组下标
int offset = 1; //设置旋转过程中的区间右值空格数
int startx = 0; //起始横坐标
int starty = 0; //起始纵坐标
int count = 1; //从1开始计数
while(loop--) { //开始循环
i = startx;
j = starty;
//方向一:从左到右
for(j = starty; j < starty + n - offset; j++) {
res[i][j] = count++;
}
//方向二:从上到下
for(i = startx; i < startx + 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 += 2; //每次循环增加两个数
}
if(n % 2) { //如果n为奇数,需要在正中心位置单独添加
int mid = n / 2;
res[mid][mid] = count;
}
return res;
}
};
本题小结:本题属于模拟类,难点在寻找循环不变量,即旋转思路。