day2| 977.有序数组的平方、209.长度最小的子数组、 59.螺旋矩阵II

977.有序数组的平方

题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep

package com.secondday.array;

/**
 * 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按非递减顺序排序。
 *
 * 示例 1:
 *
 * 输入:nums = [-4,-1,0,3,10]
 * 输出:[0,1,9,16,100]
 * 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]
 */
public class SortSqArray {
    public static void main(String[] args) {
        int[] nums = {-4,-1,0,3,10};
        nums = sortSquare(nums);
        for (int n : nums){
            System.out.print(n+" ");
        }
    }


    //相向指针写法
    public static int[] sortSquare(int[] nums){
        int left = 0;
        int right = nums.length-1;
        int[] result = new int[nums.length];
        int k = nums.length-1;

        while (left<=right){
            if (nums[left] * nums[left] < nums[right]*nums[right]){
                result[k--] = nums[right]*nums[right];
                --right;
            }else {
                result[k--] = nums[left]*nums[left];
                ++left;
            }
        }
        return result;
    }
}

小结

使用双向指针,循环条件注意left = right 边界问题,if考虑了<的情况,else考虑了>=的情况,开辟新空间新数组result来实现排序的目的

209.长度最小的子数组

题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
文章讲解:https://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE

package com.secondday.array;

/**
 * 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
 *
 * 示例:
 *
 * 输入:s = 7, nums = [2,3,1,2,4,3]
 * 输出:2
 * 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
 * 提示:
 *
 * 1 <= target <= 10^9
 * 1 <= nums.length <= 10^5
 * 1 <= nums[i] <= 10^5
 */
public class MinLengthArray {
    public static void main(String[] args) {
        int[] nums = {2,3,1,2,4,3};
        System.out.println(minSubArrayLen(nums,7));
    }

    public static int minSubArrayLen(int[] nums,int s){
        int i = 0;  //起始指针

        int result = Integer.MAX_VALUE;
        int sum = 0;  //滑动窗口的值
        
        for (int j = 0; j<=nums.length-1;j++){  //j是终止指针
            sum += nums[j];
            //滑动窗口的起始位置考虑
            while (sum>=s){   //当出现>=7的情况
                //计算出最小长度
                int minSubLen = j-i+1;
                result = Math.min(result,minSubLen);

                //终止循环的条件
                sum -= nums[i]; //向后移动一位,减去滑动窗口的头一位
                //起始位置+1
                i++;

            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;   //出现0的情况就是异常,无法满足>=7的情况
    }
}

小结

在O(1)的空间上使用双向指针,并且时间为O(n)的情况,调节指针的位置以便能达到滑动的效果

  • result值的设定
  • 起始指针跟终止指针的指向
  • 计算符合最小长度的情况
  • 异常判断

59.螺旋矩阵II

题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/

package com.secondday.array;

/**
 * 给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
 * 示例:
 * 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ]
 */
public class GenerateMatrix {

    public static void main(String[] args) {

        int[][] res = generateMatrix(3);
        for (int i = 0; i < res.length; i++) {
            for (int j = 0; j <res.length ; j++) {
                System.out.print(res[i][j]+" ");
            }
            System.out.println();
        }

    }

    public static int[][] generateMatrix(int n){
        int loop =0;    //控制循环次数
        int startx = 0; //每次循环开始点
        int starty = 0;	每次循环开始点
        int[][] res = new int[n][n];
        int i,j;		//行、列
        int count = 1; //定义填充数字
        int offset = 1; //控制右开的缩进

        while (loop++ < n/2){  //控制循环次数
            //遵循左闭右开的原则 -->循环不变量

            //模拟上侧从左到右
            for (j = starty;j<n-offset;j++){    //假设n=4,数组下标填充到2,空出3的位置留给下一次填充,并且此时索引j=3,因为最后还会再进行一次判断
                res[startx][j] =count++;
            }

            //模拟右侧从上到下
            for (i=startx;i<n-offset;i++){
                res[i][j] =count++;  //此时的j是不变,j=3
            }

            //模拟下侧从右到左
            for (;j>starty;j--){
                res[i][j] = count++;  //此时i是不变的,j从下标为3的情况进行填充,空出starty的位置留给下一次填充,并且此时的j=0
            }

            //模拟左侧从下到上
            for (;i>startx;i--){
                res[i][j] = count++; //此时的j是不变的,j=0
            }

            //由上四个for循环已经走完一圈 ,初始位置需要变化,还有offset末端距离也需要变化,offset是用来控制右开的距离缩进
            startx++;
            starty++;
            offset++;

        }

        //如果n是偶数正常填充完毕,如果n是奇数的话中间会空出一个位置,中间的位置另外填充
        if (n % 2 == 1){
            res[startx][starty] = count++;
        }

        return res;
    }
}

小结

模拟题,没有计算,看到题目知道结果,使用代码的方式进行表达出来。技巧:

  • 先找出圈数,外层循环,使用一个loop变量进行控制
  • 描写矩阵要遵从左闭右开的原则,使用offset变量控制右开,避免右开被赋值填充
  • 画好外层考虑下一层的位置
  • 最后考虑奇偶的问题,因为偶数中间不会空,奇数会空
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值