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

@代码随想录算法训练营第2天 | Leetcode977 有序数组的平方, 209 长度最小的子数组,59螺旋矩阵

977 有序数组的平方

视频链接:
https://www.bilibili.com/video/BV1fA4y1o715/?share_source=copy_web&vd_source=ea38fc37ab446e2a02645366e71adf5d

第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无)

双指针法,之前刷过,但是具体细节忘记了。

代码随想录解法思路

两边双指针。因为最大值只能出现在数组的两端(递增数组,有负数。)所以一个指针从头,另一个指针从末端遍历。首先判断左指针平方是否大于右指针平方,如果大于,就把左指针平方给右指针,然后把右指针不用平方给到左指针。然后左指针不动,右指针减一。直到左右指针相等退出循环。

c++代码具体实现注意事项

实际编写的时候出现了int超界这个错误,后来发现是end被赋值了nums.size(),这个搞错了。此外还是编译不通过,发现是对题解的理解出现了偏差。这里不应该对原数组进行改动,一旦把原数组按照上面的题解思路进行改动就打破了“最大值只能出现在两端”这个前提,所以需要new 一个result数组存储结果,两边的指针,哪个大哪个就动一下。

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

学习时长

40分钟

209 长度最小的子数组

文章链接:
【拿下滑动窗口! | LeetCode 209 长度最小的子数组】 https://www.bilibili.com/video/BV1tZ4y1q7XE/?share_source=copy_web&vd_source=ea38fc37ab446e2a02645366e71adf5d

第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无)

快慢双指针法。快指针在for循环里直接遍历,sum+=nums[快指针],当快慢指针之间的区间和大于等于target的时候,慢指针前移,需要注意这里必须要用while,也就是说快指针不是无脑前移的,还需要“快慢指针之间的区间和小于target”这个前提,所以直到slow指针增加到sum小于target就前移。

代码随想录解法思路

基本一致

c++代码具体实现注意事项

需要注意sum>=target用while做判断,因为需要直到sum小于target的时候快指针才能动。最终的子数组长度需要使用min(result, fast-slow+1)。以及注意result的初始值应该选取数组的最长长度加一,然后return可以用逻辑运算法判断是否存在子数组。

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

学习时长

30分钟

59 螺旋矩阵

视频链接:

第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无)

没什么思路,没想到螺旋矩阵有什么特点。

代码随想录解法思路

非常清晰。遵循循环不变量原则,就是左闭右开原则不变,用while循环一共有几圈,while里面四个for循环分别填充四条边,每一个while循环里需要对startx,starty和offset进行++操作,在每个for循环里面,只需要判断for i或者j的起始和终止条件,然后对相应的位置进行赋值操作即可。

c++代码具体实现注意事项

这个题一开始并没有给出完整的vector嵌套vector的定义,所以用了一个循环首先构建这样一个二维数组。需要注意如果n是奇数的情况就是startx和starty会最后走到一个点位,这个在走完while循环之后记得加一个if判断,如果是奇数就多赋值一次。
其他的没什么要注意的,主要记得左闭右开是这道题的精髓,大大简化了边界条件的判断。以及从“一共有几圈”的角度产生循环也是非常重要的。需要关注startx和starty时刻在什么位置。

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<int> a(n);
        vector<vector<int>> result;
        for(int i=0;i<n;i++){
            result.push_back(a);
        }
        int offset{1};
        int startx{0};
        int starty{0};
        int circles{n/2};
        int count{1};
        while(circles>0){
            for(; starty<n-offset; starty++){
                result[startx][starty] = count++;
            }
            for(; startx<n-offset; startx++){
                result[startx][starty] = count++;
            }
            for(; starty>offset-1; starty--){
                result[startx][starty] = count++;
            }
            for(; startx>offset-1; startx--){
                result[startx][starty] = count++;
            }
            startx++;
            starty++;
            offset++;
            circles--;
        }
        if(n%2==1){
            result[startx][starty] = count;
        }
        return result;
    }
};

学习时长

30分钟

数组专题总结

  1. 首先涉及到二分法或者多个边界条件的时候,一定在最开始就明确区间的开闭。比如是左开右闭那么后续的条件判断是大于等于,赋值操作也需要多加考虑。可以参考第一篇博客https://blog.csdn.net/weixin_46724054/article/details/129269674
  2. 数组中的元素删除,其实是把后面的覆盖被删除的value,引入了快慢双指针法。
  3. 双边双指针法使用基于两边值最大的前提,所以在移动指针重新赋值的时候注意不要打破这个假设。
  4. 快慢双指针用于筛选最小长度字数组,注意两个指针分别的移动条件。
  5. 最后的螺旋矩阵主要考察边界条件,划分圈数,划分边数可以大大清晰化问题。

你可能感兴趣的:(代码随想录算法训练营第十期,算法,矩阵,leetcode)