「代码随想录算法训练营」第二天 | 数组 part2
977.有序数组的平方
题目建议: 本题关键在于理解双指针思想
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
题目难度:简单
文章讲解:https://programmercarl.com/0977.有序数组的平方.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
题目状态:通过
个人思路:
循环平方后使用 sort
函数,具体代码如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
vector<int> res(n);
for(int i = 0; i < n; ++i)
{
res[i] = nums[i] * nums[i];
}
sort(res.begin(), res.end());
return res;
}
};
卡哥的思路(双指针):
根据卡哥的思路写的关于双指针的代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
vector<int> res(n);
int i = 0, j = n - 1, k = n - 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--;
}
k--;
}
return res;
}
};
209.长度最小的子数组
题目建议: 滑动窗口
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
题目难度:中等
文章讲解:https://programmercarl.com/0209.长度最小的子数组.html
视频讲解: https://www.bilibili.com/video/BV1tZ4y1q7XE
题目状态:有思路但出错,经ChatGPT修正后通过
个人思路:
创建两个指向数组头部的指针left
和right
,判断在这两个指针中间的子数组之和是否大于target
,并创建一个变量res = INT_MAX
,用于存储子数组大于等于target
的最小个数。
- 若大于等于,
res = min(res, right - left + 1)
,并且left++
,重新计算子数组之和; - 若小于,
right++
,并重新计算子数组之和
代码如下:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int res = INT_MAX;
int left = 0;
int sum = 0;
for(int right = 0; right < nums.size(); ++right)
{
sum += nums[right];
while(sum >= target)
{
res = min(res, right - left + 1);
sum -= nums[left];
left++;
}
}
return res == INT_MAX ? 0 : res;
}
};
59.螺旋矩阵II
题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
题目难度:中等
文章讲解:https://programmercarl.com/0059.螺旋矩阵II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
题目状态:没思路,直接看卡哥思路
代码如下:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int startX = 0, startY = 0;
int offset = 1;
int i, j;
int mid = n/2;
int loop = n/2;
int count = 1;
while(loop--)
{
i = startX;
j = startY;
for(j; j < n - offset; ++j)
{
res[i][j] = count++;
}
for(i; i < n - offset; ++i)
{
res[i][j] = count++;
}
for(j; j > startY; --j)
{
res[i][j] = count++;
}
for(i; i > startX; --i)
{
res[i][j] = count++;
}
startX++;
startY++;
offset++;
}
if(n % 2)
{
res[mid][mid] = count;
}
return res;
}
};
思路:
主要是判断好遍历在什么时候拐弯。
- 计算螺旋矩阵的圈数
loop
;计算矩阵的中心位置count
(用于奇偶);定义每圈在哪个位置拐弯(偏移量offset
);定义每圈遍历的开始位置(水平从startY
开始遍历,垂直从startX
开始遍历); - 明确什么时候开始拐弯(左闭右开);
- 每遍历一圈,下圈的开始位置(
startX
和startY
)加1,每圈的偏移量加1。