数组part2 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结
建议大家先独立做题,然后看视频讲解,然后看文章讲解,然后在重新做一遍题,把题目AC,最后整理成今日当天的博客
拓展题目可以先不做
详细布置
977.有序数组的平方
题目建议: 本题关键在于理解双指针思想
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size());
int k = nums.size()-1;
int front=0, back=nums.size()-1;
while(front<=back){
if(nums[front]*nums[front] > nums[back]*nums[back]){
result[k--] = nums[front]*nums[front];
front++;
}else{
result[k--] = nums[back]*nums[back];
back--;
}
}
return result;
}
};
209.长度最小的子数组
题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建议大家先看视频讲解。 拓展题目可以先不做。
滑动窗口和普通暴力循环的区别: 暴力中的每组i,j都进行验证,除了满足超过target条件后的j会剪枝。而滑动窗口的过程是在继续,大于等于target时,计算是否为最优值,并去除最前面的值,使得再次不满足条件。
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX; // 最终的结果
int sum = 0; // 子序列的数值之和
int subLength = 0; // 子序列的长度
//暴力解法
for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
sum = 0;
for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
sum += nums[j];
if (sum >= s) { // 一旦发现子序列和超过了s,更新result
subLength = j - i + 1; // 取子序列的长度
result = result < subLength ? result : subLength;
break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
}
}
}
//滑动窗口法以j为终点
for (int j = 0; j < nums.size(); j++) {
sum += nums[j];
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
while (sum >= s) {
subLength = (j - i + 1); // 取子序列的长度
result = result < subLength ? result : subLength;
sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
59.螺旋矩阵II
题目建议: 本题关键还是在转圈的逻辑,在二分搜索中提到的区间定义,在这里又用上了。
该问题的核心是控制好开始和结束的地方,且每次转向后开始和结束有规律的变化,没有重复和遗漏
。使用二分法的循环不变量原则,左闭右开原则。
如果是奇数,最中间一个要特意写一下,因为右开会把他遗漏掉
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));
int startx = 0, starty = 0;
int loop = n/2;
int mid = n/2;
int count = 1;
int offset = 1;
int i , j;
while(loop--){
i = startx;
j = starty;
//向右
for(j = starty;j<n-offset;j++){
res[startx][j] = count++;
}
//向下
for(i = startx; i<n-offset;i++){
res[i][n-offset] = count++;
}
//向左
for(j = n-offset; j>offset-1;j--){
res[n-offset][j] = count++;
}
//向上
for(i = n - offset; i > offset-1;i--){
res[i][starty]=count++;
}
startx++;
starty++;
offset++;
}
if(n%2) res[mid][mid] = count;
return res;
}
};
总结
题目建议:希望大家 也做一个自己 对数组专题的总结
文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E6%80%BB%E7%BB%93%E7%AF%87.html