代码随想录算法训练营第二天|有序数组的平方、长度最小的子数组(双指针解法)、螺旋矩阵

有序数组的平方 leetcode977

暴力解法 时间复杂度O(n+nlogn)

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

双指针解法 时间复杂度O(n)

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> result(nums.size(),0);
        int k=nums.size()-1;
        for(int i=0,j=nums.size()-1;i<=j;){
            if(nums[i]*nums[i]>=nums[j]*nums[j]){
                result[k--]=nums[i]*nums[i];
                i++;
            }else{
                result[k--]=nums[j]*nums[j];
                j--;
            }
        }
        return result;
    }
};

出现的错误

result[(nums.size()--)-1],一开始我是这样写的,编译出错,因为“--”操作符用于对变量自减操作,不能直接对一个表达式自减。

总结

学到了vector容器定义和初始化使用方法:

vector<int> vec;  //创建一个空的整数向量 

vector<int> vec(5);  //创建一个包含 5 个初始化为 0 的整数的向量

vector<int> vec(5,10);  // 创建一个包含 5 个初始化为 10 的整数的向量

长度最小的子数组 leetcode209

暴力解法 O(n^2) (会超时)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result=INT32_MAX;
        int sum=0;
        int len=0; //子序列长度
        for(int i=0;i<nums.size();i++){
            sum=0; 
            for(int j=i;j<nums.size();j++){
                sum+=nums[j];
                if(sum>=target){
                    len=j-i+1;
                    result=result<len?result:len;
                    break;
                }
            }
        }
        return result==INT32_MAX?0:result;
    }
};

其中INT32_MAX是32位有符号整型能表示的最大正整数,len用于记录子序列的长度,i为子数组的起点,j为子数组的终点。

出现的错误

1.第一个for循环之后没有重置sum=0。

2.第二个for循环中if语句中没有break,因为只要第一次满足sum>=target条件就一定是以当前i开头的最小子数组了,不用继续让j++,直接break跳出j的for循环,开始下一层i的for循环。

双指针移动窗口解法 O(n)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result=INT32_MAX;
        int len=0,sum=0,i=0;
        for(int j=0;j<nums.size();j++){
            sum+=nums[j];
            while(sum>=target){
                len=j-i+1;
                result=result<len?result:len;
                sum-=nums[i++];
            }
        }
        return result==INT32_MAX?0:result;
    }
};

其中j为窗口的终点,i为窗口的起点,for循环遍历终点,只要满足sum>=target,此时就是以j为窗口终点满足条件的子数组,然后通过while循环中sum-=nums[i++],更改窗口起点位置直到不满足条件,此时更新的len就是以j为窗口终点满足条件的最小子数组,然后j++继续遍历。与暴力求解相比,这样通过实时改变子数组起点的方法可以减少一层for循环。

其中为什么要使用while循环判断而不是if语句呢?因为当固定起点遍历终点,达到sum>=target时,不一定是满足条件的最小窗口,例如:[1,1,1,1,100],target=100。

螺旋矩阵Ⅱ leetcode59

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n,vector<int>(n,0));
        int startX=0,startY=0; //每一圈的起点
        int loop=n/2; //转几圈
        int count=1;
        int offset=1;
        int i,j; 
        while(loop--){
            i=startX;
            j=startY;
            for(j;j<n-offset;j++){
                result[i][j]=count++;
            }
            for(i;i<n-offset;i++){
                result[i][j]=count++;
            }
            for(;j>startY;j--){
                result[i][j]=count++;
            }
            for(;i>startX;i--){
                result[i][j]=count++;
            }
            startX++;
            startY++;
            offset++;
        }
            if(n%2==1){
                result[n/2][n/2]=n*n;
            }
        return result;
    }
};

出现的错误

while (loop--) {
        for (j= startY; j < n - offset; j++) {
            result[i][j] = count++;
        }
        for (i= startX; i < n - offset; i++) {
            result[i][j] = count++;
        }
        for (; j > startY; j--) {
            result[i][j] = count++;
        }
        for (; i > startX; i--) {
            result[i][j] = count++;
        }
        startX++;
        startY++;
        offset++;
        if(n%2==1){
        result[n/2][n/2]=n*n;
        }
    }

1.一开始我是这样写while循环的,这样写会导致进入第一个for循环之后因为i没有被初始化所以导致出错。

2.把判断n是奇数的if语句放在了while循环里面,导致当n=1时,进入不了while循环,给出的结果是[[0]],但其实应该是[[1]]。

总结

在使用for循环遍历每条边时最重要的是遵循循环不变量,也就是每条边左闭右开的原则。学到了使用vector定义二维向量的方法:vector<vector<int>> vec(n,vector<int>(m,0)),定义一个存放二维向量n行m列的容器且每个元素都初始化为0。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值