【c++刷题笔记-数组】day02:leetcode977. 有序数组的平方、leetcode 209.长度最小的子数组、leetcode 59.螺旋矩阵II

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;
    }
};

总结

数组写代码的结构很重要,先找出边界,选好遍历方式想清楚再动手

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值