题目链接: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
977.有序数组的平方
思路:
- 双指针解题,要考虑双指针的位置,在本题中一个头指针,一个尾指针(原始数组平方之后两头大中间小的特征),共同遍历数组
- 在一个for循环中,遍历数组并且比较大小,将每次平方之后较大的数放在新的数组的尾部(数组的特点,这样能够保证递增顺序)
public:
vector<int> sortedSquares(vector<int>& nums) {
int k=nums.size()-1;
vector<int> result(nums.size(), 0); //创建一个和nums一样大小元素全是零的容器
for(int i=0,j=nums.size()-1;i<=j;){ //这里的双指针一个是指的头 一个是指的尾 相互对比
if(nums[i]*nums[i]<nums[j]*nums[j]){//判断平方之后的大小
result[k]=nums[j]*nums[j];
k--; //控制result容器从大到小
j--; //控制尾指针从后往前遍历
}
else{
result[k]=nums[i]*nums[i];
k--;
i++; //控制头指针往后遍历
}
}
return result;
}
总结:自己总是想不到双指针的位置放在哪里
209.长度最小的子数组
思路:滑动窗口,双指针的变形,一个指针指向起始位置,一个指向终止位置,终止位置一直在遍历,在达到>=s的条件时,起始位置才会后移,还有就是窗口中的元素,在起始位置后移式,窗口元素和要减去后移前的起始位置
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
窗口内就是俩指针中间的元素,也就是满足>=s子数组
在达到>=s的条件时,起始位置才会后移
终止位置在for循环中进行
要用while判断sum是否满足,因为要让i连续后移,不一定后移一次
public:
int minSubArrayLen(int target, vector<int>& nums) {
int length=0;
int result = INT32_MAX;
int sum=0; //滑动窗口的和
int i=0; //起始位置
for(int j=0;j<nums.size();j++){
sum+=nums[j];
while(sum>=target){ //判断达到要求之后要做
length=j-i+1; //1.计算长度
sum=sum-nums[i]; //2.子数组和减去后移前的起始位置值
i++; //3.起始位置后移
if(length<result){ //可以换成三目运算result = result < length? result : length;
result=length;
}
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
//三目运算 return result == INT32_MAX ? 0 : result;
if(result==INT32_MAX){
return 0;
}
else
return result;
}
总结:注意判断起始位置和终止位置哪个是放在for循环中
59.螺旋矩阵II
思路:每次循环一定要做到循环不变量
- 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左列从下到上
左闭右开循环
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));
int loop=n/2; //循环的圈数
int start_x,start_y=0; //定义每一圈的起始点
int count=1;
int flag=1; //每一圈循环要减去的
int i,j; //定位 每次运行到哪
while(loop--){
i=start_x;
j=start_y;
//填充上行从左到右
for(j=start_y;j<n-flag;j++){
res[start_x][j]=count++; //行不变 列变 此时j是最右列
}
//填充右列从上到下
for(i=start_x;i<n-flag;i++){
res[i][j]=count++; //行变 列不变
}//此时i是最下行 j是最右列
//填充下行从右到左
for(;j>start_y;j--){
res[i][j]=count++; //最下边行不变 列变
}
for(;i>start_x;i--){
res[i][start_y]=count++;
}
start_x++; //一圈之后就更新起始位置
start_y++;
flag++;
}
if(n%2==1){
res[n/2][n/2]=n*n; //给中间的赋值
}
return res;
}
总结:循环不变量!!!