训练营打卡Day02
题03:977. 有序数组的平方
思路
双指针,因为很小的负数或者很大的正数,在平方之后会变成很大的正数,所以大的数字可能由左边的数字平方产生,或者右边的数字平方产生。
- 初始化一个新的数组,放置放回结果,即结果数组
- 初始化左下标和右下标
- 比较左下标值的平方和右小标值的平方,
- 如果左下标值平方大,就将左下标的平方值放到结果数组右边,左下标自减一
- 如果左下标值平方大,就将右下标的平方值放到结果数组右边,右下标自增一
自己写代码时的问题
在遍历结果数组时,下标从大到小,小标应该是自减,但是写成了自增
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int>result(nums.size(), 0);
int l = 0, r = nums.size() - 1;
for(int i = nums.size() - 1; i >= 0; i--)
{
int lsqr = nums[l]*nums[l];
int rsqr = nums[r]*nums[r];
if(lsqr > rsqr)
{
result[i] = lsqr;
l++;
}
else
{
result[i] = rsqr;
r--;
}
}
return result;
}
};
题04:209. 长度最小的子数组
思路
这道题乍一看没有什么思路,没有感觉就去看了一些题解提示“滑动窗口”,下意识就明白了要用双指针。
-
初始化结果为INT_MAX,和为0,用双指针构建一个滑动窗口
-
right管遍历,加入nums[right]的和
-
当和大于等于目标值的时候,求长度 left-right+1, 结果min(left-right+1, 结果),减去右指针的值nums[left]
-
结果返回
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0, right = 0;
int ans = INT_MAX;
int sum = 0;
while(right < nums.size())
{
sum += nums[right];
while(sum >= target)
{
ans = min(right - left + 1, ans);
sum -= nums[left++];
}
right++;
}
return ans == INT_MAX ? 0 : ans;
}
};
提交后发现的错误
- “sum >= target”的“ = ”漏掉了
- 最后如果返回值为INT_MAX,应该设为0
刷题05:59. 螺旋矩阵 II
这道题第一次刷,没一点反应,就直接看解析了
思路:
-
使用vector定义一个二维数组
-
每个圈循环几次,n/2
-
矩阵中间的位置,n/2
-
每一条边遍历的长度,循环右边界收缩
赋值的过程
- 从左到右,n-offset控制边界
- 从上到下,n-offset控制边界
- 从右到左,大于startX
- 从下到上,大于startY
一次赋值之后
startY++, startX++, offset++
若n为奇数,最后赋值中间
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>>ans(n, vector<int>(n, 0));
int startX = 0, startY = 0, offset = 1, num = 1;
int loop = n/2;
while(loop--)
{
int i = startY;
int j = startX;
for(;j < n - offset;j++)
ans[i][j] = num++;
for(;i < n - offset;i++)
ans[i][j] = num++;
for(;j > startX; j--)
ans[i][j] = num++;
for(;i > startY; i--)
ans[i][j] = num++;
startY++;
startX++;
offset++;
}
if(n % 2 == 1)
ans[n/2][n/2] = num;
return ans;
}
};