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

270 阅读1分钟

LeetCode 977.有序数组的平方

class Solution {
    public int[] sortedSquares(int[] nums) {
        int leftPointer = 0, rightPointer = nums.length - 1;
        int[] res = new int[nums.length];

        for(int i = nums.length - 1; i >= 0; i--){
            if(nums[leftPointer] * nums[leftPointer] >= nums[rightPointer] * nums[rightPointer]){
                res[i] = nums[leftPointer] * nums[leftPointer];
                leftPointer++;
            }
            else{
                res[i] = nums[rightPointer] * nums[rightPointer];
                rightPointer--;
            }
        }
        return res;
    }
}

要求算法时间复杂度O(n),故双指针。原数组有序、有负数,平方后最大的数只可能出现在原数组两头,逐渐向中间递减。有点归并排序的味道。

LeetCode 209.长度最小的子数组

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int start = 0;
        int sum = 0;
        int res = Integer.MAX_VALUE;
        for(int end = 0; end < nums.length; end++){
            sum += nums[end];
            while(sum >= target){
                res = Math.min(res, end - start + 1);
                sum -= nums[start];
                start++;
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;
    }
}

双指针实现滑动窗口,窗口右端不断增大,先加到>=target,然后收缩窗口左端,直至找到符合 sum >= target 且窗口长度最小。返回这个最小的窗口长度。

LeetCode 59.螺旋矩阵II

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];
        int upper = 0, left = 0; // 上边界和左边界
        int lower = n - 1, right = n - 1; // 下边界和右边界
        int count = 1; // 填入的数字

        while(count <= n * n){
            // 上侧从左到右
            if(upper <= lower){
                for(int j = left; j <= right; j++){
                    res[upper][j] = count++;
                }
                // 上边界下移
                upper++;
            }

            // 右侧从上到下
            if(left <= right){
                for(int i = upper; i <= lower; i++){
                    res[i][right] = count++;
                }
                // 右边界左移
                right--;
            }

            //下侧从右到左
            if(upper <= lower){
                for(int j = right; j >= left; j--){
                    res[lower][j] = count++;
                }
                // 下边界上移
                lower--;
            }

            // 左侧从下到上
            if(left <= right){
                for(int i = lower; i >= upper; i--){
                    res[i][left] = count++;
                }
                // 左边界右移
                left++;
            }
        }
        return res;
    }
}

一道常规的模拟题,代码随想录的题解其实还是写得挺复杂且容易弄混边界条件的。故我写得是移动边界的答案,对于此类螺旋矩阵之类的题目也有更高的通用性。