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

文章介绍了在有序数组中计算每个数字平方并保持非递减顺序的方法,利用双指针策略处理,同时提及了滑动窗口的概念,如在长度最小子数组问题中的应用。
摘要由CSDN通过智能技术生成

977.有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

思路

1.暴力解
2.双指针

双指针法过程图示:

由于数组本身是有序的,平方之后负数会变得很大,也就是变到右边去。
那么我们可以把绝对值大的数往右边移动
在这里插入图片描述
|-4|<10,我们记录10的平方后,移动右指针。
在这里插入图片描述
|-4|>3,记录-4的平方16。移动左指针

,

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

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

    public int[] sortedSquares(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(Math.abs(nums[left])<Math.abs(nums[right])){
               result[k]=nums[right]*nums[right];
               right--;
              
           }else{
               result[k]=nums[left]*nums[left];
               left++;
           }
           k--;
       }
       return result;
}
}

209.长度最小的子数组:滑动窗口

在这里插入图片描述
滑动窗口的移动是通过“右边拉大,左边缩小”的方式。
绿色的箭头是i,起始位置,蓝色的箭头表示j,指向窗口左边。
用一个sum记录和。此时sum=2,还未到达target=7的临界,我们需要拉大窗口。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
此时sum=8>7,到达了临界点。
这个时候,是我们第一次到达临界点,所以我们要做的事是什么?

  • 记录窗口的长度。
  • 因为题目要我们找的是最小值,我们要开始缩小窗口了。
  • 要保持绿色的指针不动,从左边开始缩小,所以我们需要一个while循环来做这个事情。
  • 更新窗口的最小长度
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
此时sum=7,而且窗口的长度是2,这就是我们要找的结果啦!
在这里插入图片描述

class Solution {
       public int minSubArrayLen(int target, int[] nums) {
        //定义窗口的起始位置
        int j=0;
        int sum=0;
        int sublen=0;//滑动窗口的长度
        int resLen=Integer.MAX_VALUE;
        for(int i=0;i<nums.length;i++){
            sum=sum+nums[i];
            //sum大于目标值进入循环,窗口需要缩小,寻找最小窗口的最小长度
            while(sum>=target){
                sublen=i-j+1;
                resLen=Math.min(sublen, resLen);
                sum=sum-nums[j];
                j++;
            }
        }
        if(resLen==Integer.MAX_VALUE){
            resLen=0;
        }
        return resLen;
    }
}

59.螺旋矩阵2

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4beabd6a0ee643b788d115ca1b9a0856.png
初始化一个n×n的矩阵,所有元素设为0。
设定初始的边界值:顶部top = 0(黑色线),底部bottom = n - 1(红线),左侧left = 0(蓝线),右侧right = n - 1(绿线)。此处-1就是排除了拐角处,拐角处让另一条边画。

  • 从左到右更新。从左边界开始到右边界。更新数组的时候行是不动的,top是固定的,列元素由i来改变。
  • 更新完之后我们需要让上边界+1,黑色的先往下移了。
    在这里插入图片描述
    接下来从上到下更新,起始是top=1了,到bottom=2。保持右边界不动,更新完矩阵后更新右边界。右边界-1,绿色线往左移动。
    在这里插入图片描述
    接下来是从右到左更新,从绿色线(right=1)起始,更新到左边界为止,保持底部边界不动,更新完矩阵后,底部边界+1,向上移动。
    在这里插入图片描述
    此时从下到上更新,bottom作为起始,保持左边界不动,更新完矩阵之后,左边界向右移动。
    在这里插入图片描述
    到这里可以看出来我们的上下左右边界又组成了一个新的正方形吧!这就是通过边界不断向内缩小的过程。
    在这里插入图片描述
class Solution {
    public int[][] generateMatrix(int n) {
       int[][] matrix = new int[n][n];
        int num = 1; // 要填充的数字
        //初始边界值
        int top = 0;//顶部边界
        int bottom = n - 1;//底部边界
        int left = 0;//左侧边界从左到右
        int right = n - 1;//右侧边界
        while(top <= bottom && left <= right){
            //从左到右
            for(int i=left;i<=right;i++){
                //开始填充
                matrix[top][i]=num;
                num++;
            }
            top++;//更新顶部的边界
             //从上到下
            for(int i=top;i<=bottom;i++){
                //开始填充
                matrix[i][right]=num;
                num++;
            }
            right--;
            //从右到左
            for(int i=right;i>=left;i--){
                 //开始填充
                matrix[bottom][i]=num;
                num++;
            }
            bottom--;
             //下到上
            for(int i=bottom;i>=top;i--){
                 //开始填充
                matrix[i][left]=num;
                num++;
            }
            left++;
        }
         return matrix;
    }
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值