代码随想录Day2:leetcode 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II C++

977.有序数组的平方

文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep

直接思路,先平方再排序

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

双指针,i从前往后,j从后往前,k指向结果数组尾部,平方结果较小的加入结果数组k位置

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

209.长度最小的子数组

文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE

暴力,超时
双指针:

int minSubArrayLen(int target, vector<int>& nums) {
        int count = 0,MinLength = INT_MAX,startpos = 0;

        for(int i=0;i<nums.size();i++){
            count += nums[i];
            cout<<nums[i];
            while(count>=target){
                MinLength = min(MinLength,i-startpos+1);
                cout<<i<<startpos<<" ";
                count -= nums[startpos];
                startpos++;
            }
        }
        return MinLength == INT_MAX? 0:MinLength;
    }

59.螺旋矩阵

文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/

代码随想录版本:
设置一个初始位置值 [ s t a r t x , s t a r t y ] [startx,starty] [startx,starty],以及每转一圈缩小值offset,分上左下右四个方向进行遍历。
在这里插入图片描述
这个方法用圈数控制外循环次数,外循环中是四个内循环,分别对上右下左四个方向进行遍历;
一次遍历行数2,列数2,对于偶数n,共需遍历n/2圈,对于奇数n,遍历完n/2圈后还剩1个中心点,需要对中心点进行处理;
每次循环完一圈需要更改起始点;
对于下一圈,尾x和y坐标都比上一行少了1,(头坐标是由起始点坐标控制的),所以再加一个变量,offset,控制尾部的结束条件;
所以外循环逻辑是

loop = n/2;
startx = 0,starty = 0,offset = 1 ;//起始点坐标,尾坐标减少值
while(loop!=0){
//遍历上方
//遍历右方
//遍历下方
//遍历左方
//更改下一圈起始点坐标
startx++;
starty++;
offset++;
}

在这里插入图片描述
内循环采用左闭右开的写法,对于每一行(列),行(列)头可以访问到,尾不可以访问,对于坐标的控制,使用的是圈起始点坐标和offset进行控制

  • 上方:横坐标不变,与起始点x坐标startx相同,for循环改变纵坐标,初始值与起始点y坐标starty相同,最后一个位置是n-offset,但是采用左闭右开写法,不可取到,所以是j<n-offset
  • 右方: 纵坐标不变,依然为n-offset,for循环改变横坐标,初始值与起始点x坐标startx相同,最后一个位置是n-offset,i<n-offset
  • 下方: 横坐标不变,是n-offset,for循环改变纵坐标,初始值n-offset,最后一个位置是starty,j>starty,j–
  • 左方:纵坐标不变,为starty,for循环改变横坐标,初始值n-offset,最后一个位置是startx,i>startx,i–
vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0));
        int loop = n/2,startx=0,starty=0,offset = 1,count = 1,i,j;
        while(loop!=0){
            //上
            for(j=starty;j<n-offset;j++){
                res[startx][j] = count;
                count++;
            }
            //右
            for(i=startx;i<n-offset;i++){
                res[i][j] = count;
                count++;
            }
            //下
            for(j;j>starty;j--){
                res[i][j] = count;
                count++;
            }
            //左
            for(i;i>startx;i--){
                res[i][j] = count;
                count++;
            }
            startx++;
            starty++;
            offset++;
            loop--;
        }
        if(n%2 != 0)    res[startx][starty] = count++;
        return res;
    }

https://leetcode.cn/problems/spiral-matrix-ii/solutions/12594/spiral-matrix-ii-mo-ni-fa-she-ding-bian-jie-qing-x/

leetcode题解区大神题解写法:
左闭右闭,采用数值作为外圈循环条件,设置四个方向t,r,b,l作为内圈循环边界,代码如下

int t=0,r=n-1,b=n-1,l=0;
        int k = 1;
        while(k<=n*n){
            //上方行,从左到右
            for(int i=l;i<=r;i++){
                res[t][i] = k;
                k++;
            }
            //写完一行,t++,因为到下一个循环时t已经增加,所以采用左闭右闭;
            t++;
            for(int i=t;i<=b;i++){
               res[i][r] = k;
                k++; 
            }
            r--;
            for(int i=r;i>=l;i--){
               res[b][i] = k;
                k++; 
            }
            b--;
            for(int i=b;i>=t;i--){
               res[i][l] = k;
                k++; 
            }
            l++;
        }
        return res;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值