题目描述:非递减数组nums,将各元素平方按非递减顺序排列,返回新数组
- 双指针:left从左往右,right从右往左,比较平方数,对新数组从大到小(从右往左)赋值
视频讲解https://www.bilibili.com/video/BV1QB4y1D7ep/?vd_source=f98f2942b3c4cafea8907a325fc56a48
笔记整理:
- 思路:
- nums元素组成可能为:①全正;②全负;③有正有负;
- 对于有正有负的情况,需要比较负数平方与正数平方,才能决定在新数组中的位置
- 用一个指针扫描负数,一个指针扫描正数,①②可合并到③(一个指针始终未更新)
- 代码:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> ans(nums.size(), 0);
int left = 0;
int right = nums.size() - 1;
for (int i = nums.size() - 1; i >= 0; i--) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
ans[i] = nums[left] * nums[left];
left++;
}
else {
ans[i] = nums[right] * nums[right];
right--;
}
}
return ans;
}
};
题目描述:给定正整数数组nums和正整数target,找和>=target的长度最小的连续子数组;找到返回其长度,找不到返回0;
- 滑动窗口:[left, right],一层for:对于每一个固定的右界,找符合条件的左界,更新最小长度
视频讲解https://www.bilibili.com/video/BV1tZ4y1q7XE/文章讲解https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html#%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%89%88%E6%9C%AC笔记整理:
- 思路:
- 暴力解法:两层for
- 外层为起始位置,每轮重置sum = 0;
- 内层为终止位置,从起始位置开始向后遍历,一旦sum >= target就break;
- 对于每个起止位置,找符合条件的最小长度子数组,判断更新result
- 每一轮固定起始位置,而终止位置会走回头路,考虑进行优化
- 滑动窗口:
- 每一轮固定终止位置
- 当sum >= target时,不断右移起始位置来缩小窗口,判断更新result
- 子数组[left, right]长度为:right - left + 1
- 暴力解法:两层for
- 代码:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left = 0;
// 当前子数组元素和
int sum = 0;
// 符合条件的子数组长度
int subLength = 0;
// 最小长度
int result = INT32_MAX;
// 移动右界
for (int right = 0; right < nums.size(); right++) {
sum += nums[right];
while (sum >= target) {
// 计算子数组长度
subLength = right - left + 1;
// 更新最小长度
result = result > subLength ? subLength : result;
// 移动左界
sum -= nums[left++];
}
}
return result == INT32_MAX ? 0 : result;
}
};
题目描述:给定正整数n,将1到n²按顺时针顺序填入n×n的正方形矩阵,返回该矩阵。
- 循环不变量:考虑每一圈的四条边按左闭右开进行处理
视频讲解https://www.bilibili.com/video/BV1SL4y1N7mV/文章讲解https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
笔记整理:
- 思路:
- 每一圈从(startx, starty)位置开始
- 上:行号不变,列号从 starty(闭)到 starty + n - offset(开)
- 右:行号从 startx(闭)到 startx + n - offset(开),列号不变
- 下:行号不变,列号从 starty + n - offset(闭)到 starty(开)
- 左:行号从 startx + n - offset(闭)到 startx(开)
- 更新startx、starty、offset(每次+2)
- n为奇数,单独处理中心位置
- 每一圈从(startx, starty)位置开始
- 代码:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
// 每一圈的起始位置
int startx = 0;
int starty = 0;
// 需处理的圈数
int loop = n / 2;
int mid = n / 2;
// 填入值
int count = 1;
// 用于确定每一圈的边长
int offset = 1;
int i, j;
while (loop--) {
// 上
for (j = starty; j < starty + n - offset; j++) {
res[startx][j] = count++;
}
// 右
for (i = startx; i < startx + n - offset; i++) {
res[i][j] = count++;
}
// 下
for (; j > starty; j--) {
res[i][j] = count++;
}
// 左
for (; i > startx; i--) {
res[i][j] = count++;
}
startx++;
starty++;
offset += 2;
}
// 对奇数单独处理
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};
数组总结
(待补充)