代码随想录算法训练营第二天| 数组 977. 有序数组的平方 209. 长度最小的子数组 59. 螺旋矩阵 II

977. 有序数组的平方

看到有序数组,目前做到的是二分法和双指针,但是二分法比较适合用在查找数字时,因此考虑使用双指针的方法。

出现错误1,直接使用j--;i++,直接使用ij进行容器运行,因为容器是需要从最后往前走的,进行else时,容器无法往前移动,因此重新定义一个tpr变量;

出现错误2.while条件设置错,因为初始化定义的时候j为size-1,表示可以取到,可以同左闭右闭区间一样理解,此时需要设置i与j相等。

修改后代码

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

209. 长度最小的子数组

写代码的时候考虑双指针,原先都写的是fast-slow,思考了半天一直不对,看了答案之后,想一想为什么是fast-slow+1。通过分析区间图,区间长度会等于尾部减首部+1.

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int tmp{0},slow{0};
        int result=nums.size()+1;
        int sum{0};
        for(int fast=0;fast<nums.size();fast++){
            cout<<result<<" "<<sum<<endl;
            sum+=nums[fast];
            while(sum>=target){
                
                if((fast-slow+1)<=result)
                {
                    result=fast-slow+1;
                }
                sum-=nums[slow];
                slow++;
            }        
        }
        return result>nums.size()?0:result;
    }
};

59. 螺旋矩阵 II

看到题目,想到不管n的数值为多大,都是进行4个方向加减,因此可以先设置方向0,1,2,3,设置全为-1的容器,如果后续达到了边界,且改边界已编辑了就需要改变方向。然后针对不同的方向,对ij进行加减,如果达到了边界并且未编辑,不能计数了,需要更改方向。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,-1));//vector如果为-1表示还没有更改,此时可以修改当前位置上的数值
        int dir{1};
        int int i=0,j=-1,m{1};//j=-1是为了使第一次循环能达到0,1,2
        while (m <= n * n) {
        if (dir % 4 == 1) {
            if (j + 1 < n && res[i][j + 1] == -1)res[i][++j] = m++;
            else ++dir;
        }
        else if (dir % 4 == 2) {
            if (i + 1 < n && res[i + 1][j] == -1)res[++i][j] = m++;//以m=3为例子,此时变成i为1变成第二行,同理,下一个循环是第三行
            else ++dir;
        }
        else if (dir % 4 == 3) {
            if (j - 1 >= 0 && res[i][j - 1] == -1)res[i][--j] = m++;
            else ++dir;
        }
        else {
            if (i - 1 >= 0 && res[i - 1][j] == -1)res[--i][j] = m++;//此时就显示了-1的重要性,为-1就不会跑到第一行了
            else ++dir;
        }
        cout<<i<<" "<<j<<endl;
    }
        return res;
    }
};

看完视频后解法:

按照二分法的知识,需要坚持循环不变量原则。一定要确定好自己使用的区间是左闭右开还是左闭右闭区间。确定好之后开始做题。视频中的方法是按照循环的圈数来的,然后前面的方法是按照数值增加到n*n的结果来的。按照循环圈数来,设置loop,每次进行一圈,在数组中分别走过两行和两列,所以loop的次数需要为n/2,然后需要设置偏置量以及下一次循环的初始位置,每进行一个循环时,偏置量及横(纵)坐标循环结束的位置都会比之前要靠前一个位置,下一次循环的初始位置也要比上一次循环的横纵坐标+1(如第一次是00,第二次起始位置便是11),然后根据移动方向设置循环终止条件即可。

错误1:未将res初始化,debug时报错了很久,以后定义容器时要记得将容器初始化后,告诉容器的规格才能进行下一步。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0));

        int loop{ n / 2 }, mid{ n / 2 };
        int startx{ 0 };
        int starty{ 0 };
        int offset{ 1 }, count{ 1 };
        int i, j;
        while (loop) {
            i = startx;
            j = starty;
            for (; j < n - offset; j++) {
                res[startx][j] = count++;
            }
            for (; i < n - offset; i++) {
                res[i][j] = count++;
            }
            for (; j > starty; j--) {
                res[i][j] = count++;
            }
            for (; i > startx; i--) {
                res[i][j] = count++;
            }
            startx++;
            starty++;
            offset++;
            loop--;
        }
        if (n % 2) {
            res[n / 2][n / 2] = n * n;
        }
                return res;
 }
       
};

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值