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

325 阅读1分钟

977.有序数组的平方

在非理想情况下,数组元素的绝对值特征符合凹陷型(先递减,再递增),可以理解为“两个有序平方数组”的有序合并问题。两个读指针分别指向首尾,比较数值并将较大的逆序填入。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int r1 = 0, r2 = nums.length - 1;
        int w = r2;
        int[] ans = new int[r2 + 1];
        while (r1 <= r2) {
            if (Math.abs(nums[r2]) >= Math.abs(nums[r1])) {
                ans[w] = nums[r2] * nums[r2];
                w--;
                r2--;
            } else {
                ans[w] = nums[r1] * nums[r1];
                w--;
                r1++;
            }
        }
        return ans;
    }
}

59.螺旋矩阵II

模拟填写流程,设置偏移量和方向,按照右下左上循环,试探边界更改方向。

class Solution {
    public int[][] generateMatrix(int n) {
        int dir = 0;
        int x = 0, y = 0;
        int[] dx = new int[]{0, 1, 0, -1};
        int[] dy = new int[]{1, 0, -1, 0};

        int[][] m = new int[n][n];

        for (int i = 1; i <= n * n; i++) {
            m[x][y] = i;
            if (x + dx[dir] >= n || x + dx[dir] < 0 || y + dy[dir] >= n || y + dy[dir] < 0 || m[x + dx[dir]][y + dy[dir]] != 0) {
                dir = (dir + 1) % 4;
            }
            x = x + dx[dir];
            y = y + dy[dir];
        }

        return m;
    }
}

*209.长度最小的子数组

初次尝试:前缀和+二分

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int[] sum = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            sum[i] += nums[i - 1] + sum[i - 1];
        }

        if (sum[n] < target) return 0;

        int lo = 1;
        int hi = n;
        while (lo < hi) {
            int mid = lo + hi >>> 1;
            boolean flag = false;
            for (int i = 0; i + mid <= n; i++) {
                if (sum[i + mid] - sum[i] >= target) {
                    flag = true;
                    break;
                }
            }
            if (flag) hi = mid;
            else lo = mid + 1;
        }

        return lo;
    }
}

看视频思路二次尝试:暴力臃肿版本

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum = 0;
        int min = Integer.MAX_VALUE;
        for (int end = 0; end < nums.length; end++) {
            sum += nums[end];
            if (sum >= target) {
                // [0, end]
                min = Math.min(min, end + 1);

                int tmp = sum;
                for (int begin = 0; begin < end; begin++) {
                    if (tmp - nums[begin] >= target) {
                        tmp -= nums[begin];
                        // (begin, end] / [begin+1, end]
                        min = Math.min(min, end - begin);
                    } else {
                        break;
                    }
                }
            }
        }

        return sum < target ? 0 : min;
    }
}

逻辑简化版本:双指针暴力

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum_prefix = 0;
        int min = Integer.MAX_VALUE;

        for (int end = 0; end < nums.length; end++) {
            // summation of [0, end]
            sum_prefix += nums[end];

            // summation of [begin, end]
            int begin = 0;
            int sum_slide = sum_prefix;
            while (sum_slide >= target) {
                min = Math.min(min, end - begin + 1);
                // reduce the slide window into [begin+1, end]
                sum_slide -= nums[begin];
                begin++;
            }
        }

        return sum_prefix < target ? 0 : min;
    }
}

滑动窗口:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int begin = 0;
        // summation of elements in sldie window
        int sum = 0;
        int ans = Integer.MAX_VALUE;

        for (int end = 0; end < nums.length; end++) {
            sum += nums[end];
            while (sum >= target) {
                ans = Math.min(ans, end - begin + 1);
                // reduce hop length implicitly
                // there is no need to set begin=0 repeatedly
                sum -= nums[begin++];
            }
        }

        return ans == Integer.MAX_VALUE ? 0 : ans;
    }
}