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

103 阅读3分钟

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]

思路

双指针法
因为数组是有序的,因此数组最后面的数字的平方一定是大于前面数的平方,但考虑到可能存在负数的原因,因此我们需要比较最左边和最右边的的数字平方的大小;
例如 (4)^2 > 3^2 但是 -4 < 3。 因此我们需要两个指针,一个指向最左边,一个指向最右边,每次比较左指针数的平方和右指针数的平方,哪个更大则放入新数组的最后面,同时移动指针。
注意: 新数组一定要从后往前,因为最大的平方一定是原数组最左或最右的数中的一个的平方,而最小的则不然。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int pre = 0;
        int post = nums.length - 1;
        int[] res = new int[nums.length];
        int idx = post;
        while (pre <= post) {
            int preNum = nums[pre] * nums[pre];
            int postNum = nums[post] * nums[post]; 
            if (postNum > preNum) {
                res[idx--] = postNum;
                post--;
            } else {
                res[idx--] = preNum;
                pre++;
            }
        }
        return res;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

参考文章

代码随想录:有序数组的平方

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

思路

快慢指针 + 滑动窗口: 快慢指针同时指向数组第一个值,快指针先以每次移动一位的速度不停的向右移动,直到快慢指针区间的数的和sum大于或等于目标值target;当 sum >= target 时,慢指针开始移动,每次右移一格,同时sum -= nums[slow++],直到和小于目标值 while (sum >= target),这个操作期间要检查区间长度是否小于已知的最短长度,如果是,则更新最小长度。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int res = Integer.MAX_VALUE;
        int slow = 0;
        int val = 0;
        for (int fast = 0; fast < nums.length; ++fast) {
            val += nums[fast];
            while (val >= target) {
                res = Math.min(res, fast - slow + 1);
                val -= nums[slow++];
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

参考文章

代码随想录:209.长度最小的子数组

59. 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

思路

思路很简单,就是简单的嵌套循环,然后需要注意的点非常多。

  1. 从左到右,从上到下,从右到左,从下到上分别用四个for循环解决;循环的次数为n/2这点如果画了图就非常清晰(如图一)。
  2. 循环不变量:坚持左闭右开原则,这里表示为从第一个数,到每一行或者每一列的倒数第二个数为止,最后一个数留给下一个for循环作为开始元素。如图二,每一种颜色代表一个for循环
  3. 判断n的奇偶,如果为奇数的话矩阵最中间的那个数字是无法遍历到的,因此我们要手动赋值。
class Solution {
    public int[][] generateMatrix(int n) {
        int loop = 0;
        int start = 0;
        int count = 1;
        int i,j;
        int[][] res = new int[n][n];
        while (loop++ < n/2) {
            for ( j = start; j < n - loop; ++j) {
                res[start][j] = count++;
            }         

            for ( i = start; i < n - loop; ++i) {
                res[i][j] = count++;
            }

            for ( ; j >= loop; --j) {
                res[i][j] = count++;
            }

            for ( ; i >= loop; --i) {
                res[i][j] = count++;
            }
            start++;
            
        }

        if (n % 2 == 1) {
            res[start][start] = count;
        }
        return res;
    }
}
  • 时间复杂度 O(n^2)
  • 空间复杂度 O(1)

image.png图1

image.png图2

参考文章

代码随想录:59. 螺旋矩阵 II