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

27 阅读3分钟

977.有序数组的平方 leetcode.com/problems/sq…

暴力解法就是遍历数组得到平方数组,然后排序,时间复杂度O(n + nlogn)

双指针解法:定义两个指针分别指向数组两端,因为是最大值嘛,然后循环判断左边的数是否比右边的大,是的话就放到result数组中,并且是从后往前放的,因为数组大小是固定的,所以知道result的对应下标

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] result = new int[nums.length];
        int k = nums.length - 1;
        for (int l = 0, r = nums.length - 1; l <= r; ) {
            // 如果左边大,就放到result中
            if (nums[l] * nums[l] > nums[r] * nums[r]) {
                result[k] = nums[l] * nums[l];
                k--;
                l++;
            } else { // 如果相等或者右边大
                result[k] = nums[r] * nums[r];
                k--;
                r--;
            }
        }
        return result;
    }
}

这个题有 Follow up:  Squaring each element and sorting the new array is very trivial, could you find an O(n) solution using a different approach?

209.长度最小的子数组

leetcode.com/problems/mi…

思路:最直接的也是两个for循环直接暴力遍历

双指针做法:也叫滑动窗口但是实际就是双指针,用两个指针放在左边起点,向右移动其中一个,判断当前形成的窗口的和是否大于target,如果大于等于则计算窗口长度,并移动左边界指针,这样窗口就变小了;如果小于则一直移动右边界指针

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
    //     // 定义两个指针,一个向右移动,计算这个区间的sum
    //     int left = 0;
    //     int right = 0;
    //     int sum = 0;
    //     // 如果sum < target,继续向右移动
    //     while (left <= nums.length - 1 && right <= nums.length - 1) {
    //         if (sum < target) {
    //             right++;
    //             sum = sum + nums[right];
    //             // 否则左边界指针向右移动
    //         } else if (sum > target) {
    //             sum = sum - nums[left];
    //             left++;
    //         } else {
    //             return right - left + 1;
    //         }
    //     }
    //     return 0;
    // }


        int left = 0;
        int right = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        while (right < nums.length) {
            sum = sum + nums[right];
            // 如果大于等于target,计算当前窗口长度
            // 要等于因为右边可能还有更短的窗口
            while (sum >= target) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left];
                left++;
            }
            right++;
        }
        // 如果没有满足target的窗口就返回0
        return result == Integer.MAX_VALUE ? 0 : result;
}
}

  1. Spiral Matrix

leetcode.com/problems/sp…

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;

        int up = 0, down = m - 1, left = 0, right = n - 1;
        List<Integer> result = new ArrayList<>();
        while (true) {
            // 从左到右
            for (int i = left; i <= right; i++) result.add(matrix[up][i]);
            // 将上边界下移 如果上边界大于下边界,则已经遍历结束
            if (++up > down) break;

            // 从上到下
            for (int i = up; i <= down; i++) result.add(matrix[i][right]);
            if (--right < left) break;

            // 从右到左
            for (int i = right; i >= left; i--) result.add(matrix[down][i]);
            if (--down < up) break;

            // 从下到上
            for (int i = down; i >= up; i--) result.add(matrix[i][left]);
            if (++left > right) break;

        }
        return result;
    }
}


59.螺旋矩阵II leetcode.com/problems/sp…

class Solution {
    public int[][] generateMatrix(int n) {
        int up = 0, down = n - 1, left = 0, right = n - 1;
        int num = 1;
        int[][] result = new int[n][n];
        while (true) {
            for (int i = left; i <= right; i++) result[up][i] = num++;
            if (++up > down) break;

            for (int i = up; i <= down; i++) result[i][right] = num++;
            if (--right < left) break;

            for (int i = right; i >= left; i--) result[down][i] = num++;
            if (--down < up) break;

            for (int i = down; i >= up; i--) result[i][left] = num++;
            if (++left > right) break; 
        }
        return result;

    }
}

跟54基本一样的思路,注意细节别写错了就行