day2
今天早上刷了一遍昨天的两道题,印象更深刻了点。拓展就等以后二刷再试试。
好的,那么回到今天的题:
977.有序数组的平方
题目链接:leetcode.cn/problems/sq…(因为再把题目描述放上来会很占篇幅,今天开始就只放链接)
这题我一开始就按照提议先将整个数组元素平方后再排序,虽然ac了但是肯定不满足。因为这段时间学的是数组,昨天重点是指针,我就从指针的方向去思考。大体的思路是:先给整个数组元素取平方,设置两个指针,分别放在数组首尾,依次对比,将较大的元素放在新数组的尾部,旧数组中较大元素对应的指针往另一个指针方向移动,直到两指针重合结束。我看了一下官方答案,确实有这个思路,一下子十分开心。以下是我的代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i = 0;
int n = nums.size();
int j = n - 1;
vector<int> ans(n, 0);
int pos = n - 1;
while (i <= j) {
if (nums[i] * nums[i] > nums[j] * nums[j]) {
ans[pos] = nums[i] * nums[i];
i++;
} else {
ans[pos] = nums[j] * nums[j];
j--;
}
pos--;
}
return ans;
}
};
答案中还有第二种,我觉得那种就有点麻烦了,而且还得考虑单个指针移动至边界的情况。
209.长度最小的子数组
这题解决的思路其实还是双指针,和上一题的区别就是这个是可以抽象为一个滑动的窗口,根据当前子序列的大小动态调节子序列的起始位置,从而省去了暴力解法里面重复的操作。
代码如下:
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = 1000001;
int i = 0; //滑动窗口起始位置
int sum = 0;//滑动窗口数值之和
int subL = 0;//滑动窗口长度
for (int j = 0; j < nums.size(); j++) {
sum += nums[j];
while (sum >= target) {
subL = j - i + 1;
result = result < subL ? result : subL;
sum -= nums[i++];
}
}
return result == 1000001 ? 0 : result;
}
};
螺旋矩阵II
这题重点不在算法,主要是构建螺旋画图的思路比较难。 一开始我看了好几分钟硬是没看懂要怎么实现,暴力解法可以是放弃了。然后看了卡哥的题解,感觉重点是处理规则要统一,这个和之前的二分很像。 代码如下:
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
int startx = 0, starty = 0; // 每一个圈的起始位置
int loop = n / 2; // 需要转的圈数
int mid = n / 2; // 矩阵中间的值
int count = 1; // 给矩阵赋的值
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i,j;
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 += 1;
}
//当n为奇数的情况
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};