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

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

977.有序数组的平方

题目链接:有序数组的平方

题目描述:

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 已按 非递减顺序 排序

思路:

题目中给的条件“非递减顺序”,那么平方后肯定是两边的元素最大,中间的元素小,那么需要将首尾的元素平方进行比较,想到用双指针法

易错点

  • 这里要想到以空间代价换取时间,可以通过新建一个数组来保存新的元素;
  • for循环可以在固定的格式上缺省一个条件,放到循环体里面执行;
  • 自己写的代码类似于两边指针同时变化,这样扫完之后元素数会少一半,可以让两边指针根据不同的情况,每次只改变一个指针,这样所有的元素都能比较。
    代码如下:
//时间复杂度:O(N)
//空间复杂度:O(N)

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

209.长度最小的子数组

题目链接:长度最小的子数组

题目描述:

给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例2:

输入:target = 4, nums = [1,4,4]
输出:1

示例3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

  • 1 <= target <= 109
  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105

思路:

想到用滑动窗口的解法(也就是双指针法)。
有几个关键的点要想清楚:

  • 如何移动起始位置;
  • 循环里的j是终止位置;
  • 如何移动起始位置;
    实质上就是先得到j后,用起始位置的i向后循环得到最短的子数组。

易错点:

  • result要赋值成INT32_MAX。
  • 循环下面的判断语句要多次判断,不能用if,要用while。
  • length计算完成后sum要减去起始值
  • 最后的return result == INT32_MAX ? 0 : result更加严谨。

代码如下:

//时间复杂度:O(N)
//空间复杂度:O(1)

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

59.螺旋矩阵II

题目链接:螺旋矩阵II

题目描述

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例1:
代码随想录算法训练营第二天 | 力扣977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II_第1张图片

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例2:

输入:n = 1
输出:[[1]]

提示:

  • 1 <= n <= 20

思路:

坚持循环不变量原则,即对每一条边的边界处理规则要相同,比如都是左闭右开。
**规律:**一个正整数n的平方生成的n×n的方阵可以绕n/2圈,若n为奇数,则最中间的数值需要单独赋值给它。

易错点:

  • i和j要放在外面赋值,不可单独放在循环里;
  • 要掌握定义一个vector数组的语句:vector res(n, vector(n, 0));
    代码如下:
//时间复杂度:O(N^2)
//空间复杂度:O(N^2)
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n, 0));
        int loop = n / 2;
        int startx = 0;
        int starty = 0;
        int offset = 1;
        int count = 1;
        int mid = n / 2;
        int i, j;
        while(loop--) {
            for(j = starty; j < n - offset; j++) {
                res[startx][j] = count++;
            }
            for(i = startx; i < n - offset; i++) {
                res[i][j] = count++;
            }
            for(; j > starty; j--) {
                res[i][j] = count++;
            }
            for(; i > startx; i--) {
                res[i][j] = count++;
            }
            startx++;
            starty++;
            offset++;
            if(n % 2 == 1) {
                res[mid][mid] = count;
            }
        }
        return res;
    }
};

今天的题目每道题其实做的都磕磕绊绊,还是细节的东西记不住或者出错。继续加油吧!

你可能感兴趣的:(代码随想录刷题ing,算法,leetcode,矩阵)