day 2 数组part02
977.有序数组的平方
平方后的最大值总是在数组的两端出现,所以考虑双指针法,从两端挑选最大值填入结果数组
vector<int> sortedSquares(vector<int>& nums)
{
for (auto &num : nums)
{
num = num * num; // 先把原数组的项全部变为平方
}
vector<int> ret(nums.size()); // 声明一个同样大小的数组用于存放结果
int idx = nums.size() - 1; // 从后往前插入数据
int head = 0, tail = nums.size() - 1; // 双指针,左闭右闭
while (head <= tail) // 左闭右闭的while循环条件
{
if (nums[head] > nums[tail]) // 将最大值填入结果数组
{
ret[idx] = nums[head++];
}
else
{
ret[idx] = nums[tail--];
}
idx--;
}
return ret;
}
时间复杂度: O(n)
空间复杂度: O(n)
209.长度最小的子数组
第一感觉是用滑动窗口
但是在head更新这里卡了好久
int minSubArrayLen(int target, vector<int>& nums)
{
int head = 0, tail = 0, sum = 0, minLen = INT_MAX;
while (tail < nums.size())
{
sum += nums[tail++];
if (sum >= target)
{
int len = tail - head;
if (len < minLen)
{
minLen = len;
}
sum -= nums[head++]; // 原来的做法只减了一次,不对的
while (sum >= target) // 正确的做法是要减少到sum比target还要小
{
int len = tail - head;
if (len < minLen)
{
minLen = len;
}
sum -= nums[head++];
}
}
}
return minLen == INT_MAX ? 0 : minLen;
}
时间复杂度: O(n)
空间复杂度: O(1)
59.螺旋矩阵II
原则:循环不变量原则
虽然知道方法但是代码实现起来还是好难
控制好边界
原先的想法是限制每一条边移动的长度,比如n=6的话,从5->3->1,每次结束一圈都要减2,但是这样实现起来很难
限制row和col的上限和下限比限制移动的步长要简单。可以理解为有一堵墙,墙在逐渐往里缩。墙的大小每次只要减1就行
我的写法:
vector<vector<int>> generateMatrix(int n) {
if (n == 1) return {{1}};
int curNum = 1, wall = 1, halfN = n / 2;
vector<vector<int>> table(n, vector<int>(n));
int row = 0, col = 0;
while (wall <= halfN)
{
for (; col < n - wall; col++)
{
table[row][col] = curNum++;
}
for (; row < n - wall; row++)
{
table[row][col] = curNum++;
}
for (; col >= wall; col--)
{
table[row][col] = curNum++;
}
for (; row >= wall; row--)
{
table[row][col] = curNum++;
}
row++;
col++;
wall++;
}
if (n & 1) // 判断是否为奇数
{
table[row][col] = curNum;
}
return table;
}