Bootstrap

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

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) {
        int k = nums.size();//最大的数在两边,所以新的数组由大到小去更新。
        vector<int> result(k);
        int i,j;
        //for循环当中,i++和j--的操作取决于数组两边的值哪个大哪个小,所以到循环里面判断
        //同样 i <= j中的等号避免i = j的时候漏掉一个元素。
        for(int n = nums.size() -1,i = 0, j = nums.size() -1 ; i <= j;)
        {
            if((nums[i] * nums[i]) <(nums[j] * nums[j]) )
            {
                result[n] = nums[j] * nums[j];
                j--;
                n--;
            }
            else
            {
                result[n] = nums[i] * nums[i];
                i++;
                n--;
            }
        }
        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

注意滑动窗口的思想

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int sum = 0;//滑动窗口中数组元素之和。
        int result = INT32_MAX;
        /*
        在 C++ 中,INT_MAX 是一个预定义的常量,表示整型(int)的最大值。这个常量定      义在 <climits> 头文件中,其实际值通常是 2^31 - 1(即 2147483647),因为 int 类型通常是一个 32 位的有符号整数,其中一位用来表示符号位。

使用 INT_MAX 可以方便地获取整型的最大取值范围,在需要对整型变量进行比较或者限制取值范围时非常有用。例如,在编写代码时,可以使用 INT_MAX 来表示整型变量的上限,或者在判断整型变量是否达到最大值时进行比较操作。
         */
        int subL,i = 0;//表示当前滑动窗口的长度,和result进行对比,选出最小的长度返回到result中。i表示起始位置,初始为0.
        //for循环中,j表示数组的终止位置,即加上前面的所有元素之和和target比较。
        for(int j = 0; j < nums.size() ; j++)
        {
            sum += nums[j];
            while(sum >= target)
            {
                subL = j - i + 1;
                sum -= nums[i];
                i++;
                result = result < subL ? result : subL;
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

注意

return result == INT32_MAX ? 0 : result;这个还不太会用。

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/

解法

其实还是循环不变量原则,也就是在对正方形每条边填数字的时候保持一个原则不变,类似于二分查找中的左闭右闭或者左闭右开原则,这道题采用的是左闭右开原则。
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        
        // 使用vector定义一个二维数组
        vector<vector<int>> nums (n, vector<int>(n, 0)); 
        
        //第一圈循环开始的坐标应该是(0,0),第二圈应该是(1,1).
        int startX = 0,startY = 0;
        
        //每行或者每列的最后一个元素是不计算在内的,那么x,y初始为1,转完一整圈以后再+1.     
        int offset = 1;

        //用来给每个位置填数字。
        int count = 1,i,j;
        
        //如果n等于4 那么会转2圈,如果n等于6会转3圈,注意最后考虑n是奇数。

        //转几圈
        int loop = n / 2;

        while(loop--)
        {
            //每一圈开始要确定开始的坐标位置
            i = startX;
            j = startY;
            
            //正方形上面一行,i不变,j++
            for(; j < n - offset ; j++)
            {
                nums[i][j] = count++;
            }

            //正方形右侧一列,j不变等于n-offset,i++
            for(; i < n - offset ; i++)
            {
                nums[i][j] = count++;
            }

            //正方形下面一行,i不变等于n-offset,j--,j不应该判断成是否大于0
            for(; j > startY ; j--)
            {
                nums[i][j] = count++;
            }

            //正方形左侧一列,j不变等于0,i++,i不应该判断成是否大于0
            for(; i > startX ; i--)
            {
                nums[i][j] = count++;
            }
            startX++;
            startY++;
            offset++;
        }
        
        //如果n是奇数
        if(n % 2 ==1)
        {
            nums[n/2][n/2] = count;
        }
        return nums ;
    }
};
还是漏洞百出,最后两个循环的判断条件错了,不应该是大于0 因为每一圈的起始坐标不同。

数组专题总结

https://programmercarl.com/%E6%95%B0%E7%BB%84%E6%80%BB%E7%BB%93%E7%AF%87.html 懒得总结了 = =

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;