文章链接:977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II
第一想法
977.有序数组的平方
看到这道题的第一想法就是暴力求解,毕竟题目也很直白,我就只想到将元素都平方后排序。这种求解方法的时间复杂度为O(nlogn)。
(知识点:sort()函数的时间复杂度为O(nlogn).)
209.长度最小的子数组
首先我想到的是先将数组从大到小排序,然后对比num[0] 和 target,若num[0] > target,则返回1;若num[0] < target,则进行一个循环,找出数组的前几个数相加后第一次大于target。若全部相加后到不能大于target,则返回0。这一思路的时间复杂度为O(nlogn)。
59.螺旋矩阵II
想用数学思想推导出规律,但是没有思路。
看完答案后的想法
977.有序数组的平方
这道题的答案式通过“双指针”的方法求解,时间复杂度是O(n)。思路是用两个指针,一个放在开始,一个放在最后,然后比较指针所在元素的平方后的结果,谁大就将其平方放入新数组的最后,以此类推。
209.长度最小的子数组
答案的思路是滑动窗口,本质也是双指针。开始将两个指针放在最开始的位置,然后移动一个指针(终点),从而得到一个区间,计算区间元素的总和,总和达到要求就更新reault。然后移动开始指针,也是计算区间长度,以此类推(注意区间长度要更新,为j - i + 1)。时间复杂度是O(n)。
59.螺旋矩阵II
这道题没有算法,主要是学习循环不变量,即对循环的处理规则要统一,如:若一边用左闭右开,则四条边都要用左闭右开。
遇到困难
977.有序数组的平方
这道题遇到的困难如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int>result(nums.size(), 0); //注意数组的大小,以防数组越界
for(int i = 0, j = k; i <= j;)
// i++和j--是有条件的,应该放在循环内
{
if(abs(nums[i]) > abs(nums[j]))
{
result[k--] = nums[i] * nums[i];# 学会这种result[k--]的简写方式
i ++;
}
else
{
result[k--] = nums[j] * nums[j];
j --;
}
}
return result;
}
};
209.长度最小的子数组
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = 1e6; // 要设置一个很大的数
int i = 0;
int sum = 0;
for(int j = 0; j < nums.size(); j++){
sum += nums[j];
while(sum >= target){
result = min(result, j - i + 1); // 区间长度为j - i + 1
sum -= nums[i]; // 和sum += nums[j] 结合起来求区间的和
i++;
}
}
return result == 1e6 ? 0 : result;
// 如果result没有被赋值的话,就返回0,否则返回赋的值
}
};
59.螺旋矩阵II
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> nums(n, vector<int>(n, 0));
// 二维数组的定义!
int setx = 0;
int sety = 0;
int setoff = 1;
int count = 1;
int loop = n / 2; // 圈数(若为奇数,应在最后再对最中间的位置赋值)
int i, j;
int mid = n / 2;
while(loop --){
i = setx, j = sety; // 要定义,不然等会循环之间的i、j 无法共用
// 都为左闭右开
for(j; j < n - setoff; j ++){
nums[i][j] = count++;
}
for(i; i < n - setoff; i++){
nums[i][j] = count++;
}
for(; j > sety; j--){
nums[i][j] = count++;
}
for(; i > setx; i--){
nums[i][j] = count++;
}
setx++;
sety++;
setoff++;
}
if(n % 2 == 1)nums[mid][mid] = count;
// 不能用if(n % 2 == 1)nums[i][j] = count;的原因:有些情况会数组越界。
return nums;
}
};
今日收获
今天花3个小时学了这三道题,学会了“双指针”“滑动窗口”以及“循环不变量”的重要性。