2021-08-03力扣每日一题

最短无序连续子数组

问题描述:

给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

请你找出符合题意的 最短 子数组,并输出它的长度。

示例1:

输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

示例2:

输入:nums = [1,2,3,4]
输出:0

示例3:

输入:nums = [1]
输出:0

思路:

  • 因为最后需要得到一个有序数组,需要子数组的左边界的值满足以下条件:
  • 左边界的值大于左边界右边所有值中的最小值。
  • 右边界的值小于右边界左边所有值中的最大值。

拿左边界来说,左边界右边的所有值中存在比左边界更小的值,那么这个更小的值就需要和左边界交换,右边界同理。

当然,这里并不是所有满足上面条件的都可以成为左边界,而是从左到右第一个满足这个条件的位置可以定义为左边界,同理,从右向左第一个满足右边界条件的位置定义为右边界。

  • 定义两个数组,一个表示第 i 号元素前面元素的最大值,另一个表示第 i 号元素后面的最小值。
  • 通过两个循环遍历求的整个数组
  • 在从左向右遍历左边界,从右向左遍历右边界

java代码:

	public int findUnsortedSubarray(int[] nums) {
        int n = nums.length;
        if(n==1){
            return 0;
        }
        if(n==2){
            return nums[0]<=nums[1]?0:2;
        }
        //pro[i]表示第i号元素前面最大的元素大小(包括i本身)
        int[] pro = new int[n];
        pro[0] = nums[0];
        //end[i]表示第i号元素后面最小的元素的大小(包括i本身)
        int[] end = new int[n];
        end[n-1] = nums[n-1];
        for (int i = 1; i < n; i++) {
            pro[i] = Math.max(pro[i-1],nums[i]);
        }
        for (int i = n - 2; i >= 0; i--) {
            end[i] = Math.min(end[i+1],nums[i]);
        }
        int pro_s = 0;
        int end_s = 0;
        for (int i = 0; i < n; i++) {
            if(end[i]!=nums[i]){
                pro_s = i;
                break;
            }
        }
        for (int i = n-1; i >=0 ; i--) {
            if(pro[i]!=nums[i]){
                end_s = i;
                break;
            }
        }
        return end_s==pro_s? 0:end_s-pro_s+1;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值