算法Day02 | 977.有序数组的平方, 209.长度最小的子数组, 59.螺旋矩阵II

977.有序数组的平方

题目链接:977.有序数组的平方
由题设条件可知,新数组最大的值在首尾两端。因此可以通过比较两端最大然后确定数组的尾,从后往前排列(题目要求新数组从小到大)。移动首尾两端数组,可以通过双指针来解决。

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

209.长度最小的子数组

题目链接:209.长度最小的子数组
滑动窗口(当然也是双指针),左、右边界都可以运动才是滑动窗口,而且基于这条性质,就可以取到所有子区间。
先通过遍历来移动滑动窗口右边界,再通过比较与目标值的大小移动左边界。

target += nums[left++];

//等价
target += nums[left];
left++;
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int res = INT_MAX, length/*窗口长度*/ = 0;
        int left = 0;//滑动窗口的左边界
        for (int right = 0; right < nums.size(); ++right) {//right滑动窗口的右边界
            target -= nums[right];
            while (target <= 0) {
                length = right - left + 1;
                res = res < length ? res : length;
                target += nums[left++];//调节窗口的左侧
            }
        }
        return res == INT_MAX ? 0 : res;//把两种情况结合到一起
    }
};


59.螺旋矩阵II

题目链接:59.螺旋矩阵II
根据题意可以按循环,按顺序遍历一圈,再重新更换起点再循环内圈 … …
用外圈循环的索引可以表示下一圈的初始位置。
每一次元素移动都在加1,相当于记数,因此也可以用来做循环跳出条件。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n,-1));
        int left = 0, right = n - 1, top = 0, bottom = n - 1;//每组循环的边界
        int cnt = 1;
        while (cnt <= n * n) {
            for (int i = left;i <= right; ++i) {
                res[top][i] = cnt++;
            }
            //规定了下一边的上边界
            //同时给第二组循环用的,向内逼近,上边界就++,下边界就--
            ++top;
            for (int i = top;i <= bottom; ++i) {
                res[i][right] = cnt++;
            }
            --right;
            for (int i = right;i >= left; --i) {
                res[bottom][i] = cnt++;
            }
            --bottom;
            for (int i = bottom;i >= top; --i) {
                res[i][left] = cnt++;
            }
            ++left;
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值