代码随想录(数组2) | 有序数组的平方&长度最小的子数组&螺旋矩阵

977.有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解: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

重点: 双向的指针移动

代码实现

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

209.长度最小的子数组

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解: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

重点:

滑动窗口区别于暴力破解的是:
滑动窗口是遍历到当前位置的时候,循环处理左边的区间,找到左边的最小区间

代码实现
这里用deque实现了一下,deque的方式实现了滑动窗口,更容易理解

//滑动窗口最重要的是窗口的左边是需要移动,移动的去找最短的
//使用deque的方式实现
int min_array_len(vector<int> & nums, int target) {
    int sum = 0;
    int len = INT32_MAX;
    deque<int> deq;

    for(int i = 0; i < nums.size(); i ++) {
        deq.push_back(nums[i]);
        sum += nums[i];
        //如果大于sum,说明里面的值可能有多的,需要移动deque的开始位置,循环删除deque的front
        while(sum >= target) {
            len = len > deq.size() ? deq.size() : len; 
            sum -= deq.front(); 
            deq.pop_front();
        }
    }

    return len == INT32_MAX ? 0 : len;
}

//滑动窗口最重要的是窗口的左边是需要移动,移动的去找最短的
int minSubArrayLen(vector<int> & nums, int target) {
    int sum = 0;
    int len = INT32_MAX;
    int sub_start_index = 0;

    for(int i = 0; i < nums.size(); i ++) {
        sum += nums[i];
        //如果大于sum,说明里面的值可能有多的,需要移动开始位置
        while(sum >= target) {
            int temp_len = i - sub_start_index + 1;
            len = len > temp_len ? temp_len : len; 
            sum -= nums[sub_start_index]; //减掉区间起始位置,滑动串口左边向右移动
            sub_start_index ++;
        }
    }

    return len == INT32_MAX ? 0 : len;
}

59.螺旋矩阵II

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/

重点:

多画图,多画图,多画图!!!
注意循环不变量,每次都按照左闭右开的方式
由于代码习惯,这里的X轴是j,Y轴是i

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> vec(n,vector<int>(n,0));
        int loop = n/2; // 循环的圈的总数数
        int startx = 0; //x 轴的起始位置
        int starty = 0; //y 轴的起始位置
        int exec_count = 1; // 第几圈
        int count = 1; // 填充的数据,每填充一次,加一
        while(loop --) {
            int i = starty;  //i是Y轴
            int j = startx;  //j是x轴
            //第一条边 [ i = starty ][j 初始值是starty ,j++ 小于边长变量结束 ]
            int side_len = n - exec_count;
            for(;j < side_len; j ++) {
                vec[i][j] = count++;
            }
            //右边的列,[i 初始值是starty,然后++ ,小于边长结束遍历][j = 最大值,在上一次循环中已经是最大了]
            for(; i < side_len; i ++) {
                vec[i][j] = count++;
            }
            //下边的边,[i 是边的长度,上次循环中已经是最大值可以直接用][j初始值是边长,然后j -- 减到x轴的起始值] 
            for(j = side_len; j > startx; j --) {
                vec[i][j] = count++;
            }
            //左边的边,[i 初始值是边长 然后i--,结束值是starty ][j 是startx ]
            for(i = side_len; i > starty; i --) {
                vec[i][j] = count++;
            }
            startx ++;
            starty ++;

            exec_count ++;
        }

        if (n%2 == 1) {
            vec[n/2][n/2] = count;
        }
        return vec;
    }
};
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值