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

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

LeetCode977. 有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/description/
视频讲解:

自己实现

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> res;

        int z;
        for(z = 0; z < nums.size(); z++) {
            if(nums[z] >=0) break;
        }

        int l = z - 1, r = z;
        while(l >= 0 && r < nums.size()){
            int a = nums[l] * nums[l];
            int b = nums[r] * nums[r];
            if(a < b){
                res.push_back(a);
                l--;
            }else {
                res.push_back(b);
                r++;
            }
        }
        while(l >= 0) {
            res.push_back(nums[l] * nums[l]);
            l--;
        }

        while(r < nums.size()) {
            res.push_back(nums[r] * nums[r]);
            r++;
        }
        return res;
    }
};

看了carl的题解感觉自己的有点傻,虽然时间复杂度也是 O(n) 的

题解

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int k = nums.size() - 1;
        vector<int> res(nums.size(), 0); // 这里跟上面的k要区分开来,上面的k指向数组最后一个数,这里是初始化数组大小

        int l = 0, r = nums.size() - 1;

        while(l <= r){
            int a = nums[l] * nums[l];
            int b = nums[r] * nums[r];
            if(a > b){ // 跟自己写的方法相反,最大的先写进数组,所以选大的
                res[k--] = a;
                l++;
            }else {
                res[k--] = b;
                r--;
            }
        }
        return res;
    }
};

总结

  • 总是按照常规想问题,这个问题其实从后往前写会写的更顺,我那样正着去实现考虑的东西更多,麻烦了

LeetCode209. 长度最小的子数组

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/description/
视频讲解:

自己实现

暴力
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int mlen = INT_MAX;
        for(int i = 0; i < nums.size(); i++) {
            int sum = 0, len = 0;
            for(int j = i; j < nums.size() && sum < target; j++) {
                sum += nums[j];
                len++;
            }
            
            if(sum >= target)
                mlen = min(mlen, len);
        }
        return mlen == INT_MAX ? 0 : mlen;
    }
};
看思路以后
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        
        int sum = 0;
        int mlen = INT_MAX;
        int l = 0, r = -1;
        int size = nums.size();
        while(l < size && r < size) {
            if(sum < target) { // 小了就移动右边窗口,扩大
                r++;
                if(r < size) sum += nums[r];
            }else { // 大了就移动左边窗口,减小
                int len = r - l + 1;
                mlen = min(len, mlen);
                sum -= nums[l];
                l++;
            }
        }
        return mlen == INT_MAX ? 0 : mlen;

    }
};

题解

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int sum = 0;
        int mlen = INT_MAX;
        int l = 0, r = -1;
        int len = 0;
        for(int r = 0; r < nums.size(); r++) { // 控制右边窗口
            sum += nums[r];

            while(sum >= target) {
                len = r - l + 1;
                mlen = min(mlen, len);
                sum -= nums[l];
                l++;
            }
        }
        return mlen == INT_MAX ? 0 : mlen;
    }
};

总结

  • 暴力解法是用两层 for 循环,外层控制开始位置,内层控制结束位置
  • 如何使用一个for 循环实现,如果还是控制开始位置跟暴力法还是一样,因此为了跳出这个方法,用循环控制结束位置
  • sumtarget 的关系来控制滑动窗口的移动

LeetCode59. 螺旋矩阵 II

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/description/
视频讲解:

自己实现

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {

        vector<vector<int>>res(n, vector<int>(n, 0));

        int dx[4] = {0, 1, 0, -1};
        int dy[4] = {1, 0, -1, 0};
        int x = 0, y = 0;
        int c = 0;
        for(int i = 1; i <= n * n; i++) {
            res[x][y] = i;

            int a = x + dx[c];
            int b = y + dy[c];

            if(a >= n || a < 0 || b >= n || b < 0 || res[a][b]) {
                c = (c + 1) % 4;
                a = x + dx[c];
                b = y + dy[c];
            }
            x = a, y = b;
        }
        return res;

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值