第二天|977.有序数组的平方,209.长度最小的子数组(ACM模式)

文章讲解:977.有序数组的平方209.长度最小的子数组
状态:学习


一、977.有序数组的平方

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

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

算法:双指针(相向指针)
用两个指针来找符合题目条件的元素,并将元素储存在一个新数组中
难点:有负数的平方后的排序
思路:因为数组是一个非递减排序的,所以平方后的最大数在两端.
因此本题用双指针(相向指针)再合适不过了

import java.util.Arrays;
import java.util.ArrayList;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        ArrayList<Integer>nums=new ArrayList<>();
        int n,val;
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        //val=sc.nextInt();
        for(int i=0;i<n;i++){
            nums.add(sc.nextInt());
        }
        int[] arr=new int[nums.size()];
        int left=0,right=nums.size()-1;
        int index=nums.size()-1;
        while(left<=right)
        {
            if(nums.get(left)*nums.get(left)>nums.get(right)*nums.get(right))
            {
                arr[index--]=nums.get(left)*nums.get(left);
                left++;
            }else{
                arr[index--]=nums.get(right)*nums.get(right);
                right--;
            }
        }
        for(int i=0;i<nums.size();i++)
        {
            System.out.print(arr[i]+" ");
        }
    }
}

二、209.长度最小的子数组(ACM模式)

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

示例:

输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

算法:滑动窗口(双指针)
难点:要不断更新区间来找最小长度
思路:当看到题目要找 最小 连续子数组
,看到连续区间就联想起了双指针(快慢指针),
快指针先找满足条件元素,然后慢指针更新区间下标
因为还要找最小长度,以此慢指针要不断向前缩小范围,
因为这两个指针在数组就像一个窗口一样慢慢向前移动,所以这个被称为滑动窗口

import java.util.Arrays;
import java.util.ArrayList;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        ArrayList<Integer>nums=new ArrayList<>();
        int n,val;
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        val=sc.nextInt();
        for(int i=0;i<n;i++){
            nums.add(sc.nextInt());
        }
        int sum=0,min=1000005;
        int right=0,left=0;
        for(;right<n;right++){
            sum+=nums.get(right);
            while(sum>=val)
            {
                if(min>right-left+1)
                //注意作者第一次写的时候,因为没有给min进行有效的初始化,很难受,
               //当求最小值时,要将min初始化一个最大值,让第一次数据来更新这个min,进行有效初始化
                {
                    min=right-left+1;
                }
                sum-=nums.get(left);
                left++;
            }
        }
        System.out.println(min);

    }
}

总结

提示:
977.有序数组的平方:是用相向指针来解决,两个指针找,存储在另一个数组中
209.长度最小的子数组:是用快慢指针(滑动窗口)来解决,精髓在left指针要缩小范围慢慢逼近min,将while中合法范围无限逼近不合法的min

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值