leetcode977. 有序数组的平方
1,最简单的做法,原地相乘后再排序
遍历一次时间复杂度为O(n),sort基于快速排序时间复杂度为O(nlogn),所有时间复杂度为O(nlogn),空间复杂度为O(1)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i=0;i<nums.size();i++){
nums[i]=nums[i]*nums[i];
}
sort(nums.begin(),nums.end());
return nums;
}
};
2,优化做法,题目重点为非递减排序的数组,利用双指针进行遍历
需要额外的一个数组,时间复杂度O(n),空间复杂度O(n)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n=nums.size()-1;
vector<int>ans(n+1);
for(int i=0,j=n;i<=j;){
if(nums[i]*nums[i]<=nums[j]*nums[j]){
ans[n--]=nums[j]*nums[j];
j--;
}else{
ans[n--]=nums[i]*nums[i];
i++;
}
}
return ans;
}
};
我犯的错误:没用额外数组进行存储,原地交换导致数据溢出
leetcode 209.长度最小的子数组
第一想法就是暴力遍历,但是滑动窗口方法更快更好,其实就是双指针,题目重点子数组。
写滑动窗口的技巧需要掌握好,不然知道是用什么方法,但是写不出来就尴尬了。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int n=nums.size();
int s=0,slow=0,ans=INT_MAX;
for(int fast=0;fast<n;fast++){
s+=nums[fast];//统计是否达到目标值
while(s>=target){
int t=fast-slow+1;
ans=t<ans?t:ans;
s-=nums[slow];
slow++;
}
}
return ans==INT_MAX?0:ans;
}
};
我犯的错误:1,ans设置为0,结果一直为0
2,写出的代码结构很差,无法完成条件
leetcode 59.螺旋矩阵II
模拟数组,重点找好遍历方式,判断好边界。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>>a(n,vector<int>(n,0));//2维数组模拟螺旋矩阵
int t=n/2,mid=n/2;//t为循环次数,mid为当n为单数时的中间数
int offset=1,count=1;//offset限制每次填充的长度左闭右开,count为填充的数
int x=0,y=0;//起始位
int i,j;
while(t--){//判断旋转t次
for(j=y;j<n-offset;j++){//从左到右
a[x][j]=count++;
}
for(i=x;i<n-offset;i++){//从上到下
a[i][j]=count++;
}
for(;j>y;j--){//从右到左,j>起始位y
a[i][j]=count++;
}
for(;i>x;i--){//从下到上,i>起始位x
a[i][j]=count++;
}
offset++;
x++;
y++;
}
if(n%2){
a[mid][mid]=count;//中间数填充
}
return a;
}
};
总结
数组写代码的结构很重要,先找出边界,选好遍历方式想清楚再动手