day02 打卡977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

day02 打卡977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方

977题目链接

1.暴力解法。各个数平方后,调用Arrays的sort()直接排序。sort()的时间复杂度是O(n*log(n))

class Solution {
    public int[] sortedSquares(int[] nums) {
        for (int i = 0 ; i< nums.length ; i++) {
            nums[i] = nums[i] * nums[i];
        }
        Arrays.sort(nums);
        return nums;
    }
}

2.双指针法。两端的数肯定是最大之一,左指针指向0,右指针指向n-1。比较两者平方大小,大的就放到新数组的尾巴。最大的一方指针向前或向后移动,循环比较大小。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int n = nums.length;
        int[] result = new int[n];
        int left = 0;
        int right = n-1;
        int index = n-1;
        while(left <= right) {
            if (nums[left] * nums[left] < nums[right] * nums[right]) {
                result[index] = nums[right] * nums[right];
                right--;
            } else {
                result[index] = nums[left] * nums[left];
                left++;
            }
            index--;
        }
        return result;
    }
}

209.长度最小的子数组

209题目链接

1.暴力解法。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int min = Integer.MAX_VALUE;
        int sum = 0;
        int length = 0;
        for (int i = 0 ; i<nums.length ; i++) {
            sum = 0;
            for (int j = i; j<nums.length ; j++) {
                sum += nums[j];
                if (sum >= target) {
                    length = j-i+1;
                    min = length < min ? length : min;
                    break;
                }
            }
        }
        return min == Integer.MAX_VALUE ? 0 : min;
    }
}

2.滑动窗口。想不出来解法,先看了视频,然后在自己写了一遍。

视频链接

这是我看完写的版本,虽然运行成功,但是理解出现了偏差。

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

注意:因为是连续最小和。所以每次i不需要重新从下标0开始,直接是从上一次的最左边开始。int i = 0要放到循环的外面。

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

59.螺旋矩阵II

59题目链接

画图后,发现是有规律的。可以一圈一圈地顺时针顺序赋值。需要注意n偶数还是奇数需要不同处理的地方。n=4和n=5时,循环次数是2,但是奇数的中间还需要一个值,即25。

一开始没有借助开始坐标的xy值和offset,导致很多for循环里面的意思很复杂。

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] result = new int[n][n];
        if (n%2 != 0) {
            // 奇数
            result[n/2][n/2] = n*n;
        }
        // 需要循环的圈层
        int loop = n/2;
        // 需要遍历的长度,n-1,n-2,n-3...
        int offset = 1;
        // 开始的数字
        int start = 1;
        // 开始的横坐标
        int startX = 0;
        // 开始的纵坐标
        int startY = 0;
        int i = 0, j = 0;
        while (loop >= 1) {
            for (j = startY ; j<n-offset ; j++) {
                result[startX][j] = start++;
            }
            for (i = startX ; i<n-offset ; i++) {
                result[i][j] = start++;
            }
            for ( ; j>startY ; j--) {
                result[i][j] = start++;
            }
            for ( ; i>startX ; i--) {
                result[i][startY] = start++;
            }

            loop--;
            offset++;
            startX++;
            startY++;
        }
        return result;
    }
}

数组篇总结

需要掌握二分查找,看到有序数组,就可以想想能不能使用二分查找解决。并且注意界限,我一般使用left<=right的界限,即左闭右闭。

需要掌握双指针法,如快慢指针和两端指针,每次写题目都联想不到使用双指针,需要看了代码随想录的提醒之后才能想得到使用方法。

二维数组的螺旋矩阵需要明晰的界定。每次循环的数与数之间不能重合。

参考资料

代码随想录

posted @ 2023-03-02 16:42  zzzzzzsl  阅读(223)  评论(0)    收藏  举报