977. 有序数组的平方
思路1
平方+排序
思路2
双指针
- 因为有负数的存在,所以负数的平方变为正数后,有可能是最大的。
- 所以最大的数只可能在两边。
- 所以两个指针分别指向两边,然后新建一个数组,从后往前给数组赋值即可。
代码
vector<int> res(nums.size(),0);
int i = 0, j = nums.size()-1,k=nums.size()-1;
while(i<=j){
if(nums[i]*nums[i]>nums[j]*nums[j]){
res[k--]=nums[i]*nums[i];
i++;
}else{
res[k--]=nums[j]*nums[j];
j--;
}
}
return res;
209. 长度最小的子数组
思路1:暴力
这道题首先可以用两个for循环暴力求解,两个for循环,两个指针一前以后也可以表示区间。然后进行求解。
思路2:滑动窗口
滑动窗口的核心要点就是首先要满足条件,满足条件后开始改变。
- 一开始使用for循环求和,直到满足条件。
- 之后开始改变,依次删除第一个元素,直到再次不满足条件。
- 重复第一步。
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0; // 滑动窗口数值之和
int i = 0; // 滑动窗口起始位置
int subLength = 0; // 滑动窗口的长度
for (int j = 0; j < nums.size(); j++) {
sum += nums[j];
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
while (sum >= s) {
subLength = (j - i + 1); // 取子序列的长度
result = result < subLength ? result : subLength;
sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
59 螺旋矩阵 II
要点:
- 计算每条边横纵坐标的变化规律。
- 计算循环的圈数。
- 循环。
注意事项:
- 每条边循环的时候需要恒定起始位置。
- 边界的地方每次循环都会发生变化
代码
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> a(n, vector<int>(n, -1));
int startx = 0, starty = 0, i = 0, j = 0, count = 1, offset = 1;
int total = n / 2;
while (total--) {
for (j = starty; j < n - offset; j++) {
a[startx][j] = count++;
cout << a[i][j] << " ";
}
cout << endl;
for (i = startx; i < n - offset; i++) {
a[i][j] = count++;
cout << a[i][j] << " ";
}
cout << endl;
for (; j > starty; j--) {
a[i][j] = count++;
cout << a[i][j] << " ";
}
cout << endl;
for (; i > startx; i--) {
a[i][j] = count++;
cout << a[i][j] << " ";
}
cout << endl;
startx++;
starty++;
offset++;
}
if (n % 2 == 1) {
a[n / 2][n / 2] = n * n;
}
return a;
}
};