977.有序数组的平方
题目建议: 本题关键在于理解双指针思想
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
大型概括:双指针
1.题目描述-->思路:
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100]
2.输入 返回值:
vector<int> sortedSquares(vector<int>& nums)
思路:
暴力解法01:各项先平方,再sort begin() end()
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i = 0;
for(i=0;i<nums.size();i++){ //写的while 忘记 i++了!
nums[i] = nums[i]*nums[i];
}
sort(nums.begin(),nums.end());
return nums;
}
};
双指针法02:step1:申请vector没有确定大小,超时了。
step2:双指针在首尾,收缩!!
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int>result(nums.size()); //申请vector大小 踩坑!
int i = 0;
int j = nums.size()-1;
int k = j;
while(i<=j){
int x = nums[i];
int y = nums[j];
if(x<0&&-x>=y){ //慢指针动 当慢数值大的时候;
result[k] = x*x;
i++;
k--;
continue;
}
if(x<0&&-x<y||x>=0){ //快指针动,快的大
result[k] = y*y;
j--;
k--;
continue;
}
}
return result;
}
};
03:正版方法:逻辑判断的优化
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int>result(nums.size()); //申请vector大小 踩坑!
int i = 0;
int j = nums.size()-1;
int k = j;
while(i<=j){
int x = nums[i]*nums[i];
int y = nums[j]*nums[j];
if(x>y){
result[k] = x;
i++;
k--;
}
else{result[k] = y;
j--;k--;
}
}
return result;
}
};
3.边界情况:(无)
4.时间复杂度:O(n) O(n)
5.进一步优化: 03 思路
209.长度最小的子数组
题目建议: 本题关键在于理解滑动窗口,这个滑动窗口看文字讲解 还挺难理解的,建议大家先看视频讲解。 拓展题目可以先不做。
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解: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
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
大型概括:双指针
1.题目描述-->思路:
2.输入 返回值:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int minLong = INT_MAX;
int sum=0;//集合总和
int i=0;
for(int j=0;j<nums.size();j++){
sum+=nums[j];
while(sum>=target){ //一旦大于等于就开始 收缩窗口!
sum-=nums[i];
minLong=min(minLong,j-i+1);
i++;
}
}
return minLong==INT_MAX?0:minLong;
}
};
59.螺旋矩阵II
题目
大型概括:方法
螺旋存储 123、、、n...n^2
1.题目描述-->思路:
2.输入 返回值:
vector<vector<int>> generateMatrix(int n)
思路:step1:旋转后,每次留下最后一行
step2:起始点偏移! 就是 starx++ stary++ !
stpe3:注意offset 缩圈!
思路:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int count = 1; // 用来给矩阵中每一个空格赋值
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i,j;
while (loop --) {
i = startx;
j = starty;
// 下面开始的四个for就是模拟转了一圈
// 模拟填充上行从左到右(左闭右开)
for (j; j < n - offset; j++) {
res[i][j] = count++;
}
// 模拟填充右列从上到下(左闭右开)
for (i; i < n - offset; i++) {
res[i][j] = count++;
}
// 模拟填充下行从右到左(左闭右开)
for (; j > starty; j--) {
res[i][j] = count++;
}
// 模拟填充左列从下到上(左闭右开)
for (; i > startx; i--) {
res[i][j] = count++;
}
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset += 1;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};