977.有序数组的平方
题目:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
思路:首先可以想到的是用暴力解法先平方在排序,排序需要用到快排降低复杂度。但此题给出的数组已经排序好了,可以看出平方后的最大值要么在最左边,要么在最右边,因此可以想到双指针,用 left , right 指针不断找出最大值。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n=nums.size();
int left=0;
int right=n-1;
int cnt=n-1;
vector<int> ret(n);//建立一个大小为n的新数组
while(left <= right){//循环条件是left<=right,最后要处理两个元素
//这里将数组平方
int a = nums[left];
int b = nums[right];
a *= a;
b *= b;
//这里比较大小
if(a>b){
ret[cnt] = a;
left++;
}else{
ret[cnt] = b;
right--;
}
cnt--;
}
return ret;
}
};
时间复杂度:
空间复杂度:
209.长度最小的子数组
题目:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路:第一个方法是用两个for循环列出所有可能的数组再去最小长度,不过时间复杂度为,明显超时了;第二个方法可以用滑动窗口,也可以说是双指针了。首先用 j 来标记窗口终止位置,用i标记起始位置,每次循环不断更新 i ,时间复杂度降低到了
。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n = nums.size();
int sum=0;//连续的数组之和
if(n==0) return 0;
int ans = INT_MAX;//ans为滑动窗口长度
int i=0,j=0;//i为滑动窗口起始位置,j为终止位置
while(j<n){
sum+=nums[j];//从起始位置i开始,每次向后加一位
while(sum>=target){
ans = min(ans,j-i+1);//更新长度
sum-=nums[i++];//更新i位置,sum需要减去nums[i]
}
j++;//更新终止位置
}
return ans == INT_MAX? 0:ans;
}
};
时间复杂度:
空间复杂度:
59. 螺旋矩阵 II
题目:给你一个正整数
n
,生成一个包含1
到n2
所有元素,且元素按顺时针顺序螺旋排列的n x n
正方形矩阵matrix
。
思路: 本题需要模拟顺时针画矩阵,这里可以坚持左闭右开原则,如图,将每一圈分为四个模块,都是左闭右开,这样不容易乱。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> ret(n,vector<int>(n));
int startx=0,starty=0;//横纵坐标起始位置
int loop=n/2;//循环的圈数
int mid=n/2;//若n为奇数,中点坐标
int count = 1;//给矩阵赋值
int offset = 1;//每圈中,矩阵边界减去的值
int i,j;
while(loop--){
i=startx;
j=starty;
//第一块
for(;i<n-offset;i++){
ret[j][i]=count++;
}
//第二块
for(;j<n-offset;j++){
ret[j][i]=count++;
}
//第三块
for(;i>offset-1;i--){
ret[j][i]=count++;
}
//第四块
for(;j>offset-1;j--){
ret[j][i]=count++;
}
offset++;
startx++;
starty++;
}
if(n%2==1){//若n为奇数,则需给中点赋值
ret[mid][mid]=count;
}
return ret;
}
};
时间复杂度:
空间复杂度: