Bootstrap

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

977.有序数组的平方

题目链接:977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

思路

数组其实是有序的, 只不过最小的负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

  1. 确定循环次数,先准备一个返回结果的数组,每个格子都要填满,次数就是nums.length

  2. 双指针分别指向头尾,结果集指针指向最后(结果集为升序最大的元素放最后
    pic1

  3. 比较头尾的平方谁大,大的就放到下面数组最后一个位置(结果数组是升序)
    pic2

  4. 将较大的元素指针移动到中间,同时结果集指针向前移
    在这里插入图片描述

Java实现

    public int[] sortedSquares(int[] nums) {
        // 双指针
        int begin = 0;
        int end = nums.length - 1;

        // 结果集
        int[] result = new int[nums.length];

        System.out.println();
        for(int i = nums.length - 1; i >= 0; i--) {
            // 头尾的平方数
            int beginNum = nums[begin] * nums[begin];
            int endNum = nums[end] * nums[end];

            if(beginNum > endNum) { //头>尾,把头的值给结果集,头往前移
                result[i] = beginNum;
                begin++;
            } else { //头<=尾,把尾的值给结果集,头往前移
                result[i] = endNum;
                end--;
            }
        }

        return result;
    }

209.长度最小的子数组

题目链接:209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target长度最小的 子数组[numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

思路

使用双指针构造一个区间。动态判断每个区间是否是最短长度的
以题目中的示例来举例,target=7, 数组是 2,3,1,2,4,3
1、快指针遍历素组,慢指针不动,窗口长度增大。

例如从下图中的[2],移动到[2,3,1,2]
在这里插入图片描述
2、当窗口中的值>=target时,快指针停止,慢指针开始往前移动,窗口缩小,同时判断窗口中的元素和是否>=target,如果依然满足,会再往前移动,直到窗口中的值<target。每次慢指针移动时,都会记录窗口长度,看是否为最小长度。

例子如下:
1、当窗口为[2,3,1,2]时,和为7,满足条件,记最小距离为4;
2、索引j停止移动,i开始前移,区间为[3,1,2],不满足条件;
3、索引i停止,j前移,区间为[3,1,2,4];满足条件,此时区间长度为4,与最小距离相同,不做覆盖;
4、索引i停止,j前移,区间为[1,2,4];满足条件,此时区间长度为3,小于最小距离4,进行覆盖;
后续重复上述操作,直到遍历完数组
在这里插入图片描述

Java实现

    public int minSubArrayLen(int target, int[] nums) {
        int begin = 0;
        int sum = 0;
        int min_len = Integer.MAX_VALUE; //如果初始化为0,下面要先赋值再判断,这个最小长度就无法更新

        for(int end = 0; end < nums.length; end++) {
            sum += nums[end]; // 更新区间内元素和

            while(sum >= target) {
                int len = end - begin + 1; // 获取区间长度,索引相减要加1
                min_len = min_len > len ? len : min_len; // 判断目前区间长度是否为最小
                sum -= nums[begin++]; // 慢指针前移,同时更新区间内元素和
            }
        }

        return min_len == Integer.MAX_VALUE ? 0 : min_len; // 如果元素和一次都不满足条件,返回0
    }

59.螺旋矩阵II

题目链接:59.螺旋矩阵II

;