LeetCode: 581. Shortest Unsorted Continuous Subarray

30 篇文章 0 订阅
21 篇文章 0 订阅

Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too.

You need to find the shortest such subarray and output its length.

Example 1:

Input: [2, 6, 4, 8, 10, 9, 15]
Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.

Note:

  1. Then length of the input array is in range [1, 10,000].
  2. The input array may contain duplicates, so ascending order here means <=.

题意:给定序列,返回需要重排的最短子序列长度。
分析:去除需要重排的子序列之后的数据必然是在正确顺序的位置上面。所以只要确定两边最开始不在正确位置上的数即可。
方法一:将数据排序,然后从前向后扫描找到最开始处于不正确位置的数据,从后向前扫描找到最后处于不正确位置的数据。复杂度O(nlogn)。
代码如下:

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int[]sort=new int[nums.length];
        for(int i=0;i<nums.length;i++)
            sort[i]=nums[i];
        Arrays.sort(sort);
        int start=nums.length-1;
        for(int i=0;i<nums.length;i++)
            if(nums[i]!=sort[i])
            {
                start=i;
                break;
            }
        int ed=start-1;
        for(int i=nums.length-1;i>start;i--)
            if(nums[i]!=sort[i])
            {
                ed=i;
                break;
            }
        return ed-start+1;
    }
}

方法二:
换一种思路,同上只要从前向后找到第一个不在其位的数A,从后向前找到第一个不在其位的数B,中间的数即是需要重新排序的最小序列。复杂度是O(n)。
从前向后扫描,当前数如果在其位,则必然当前数是之前序列的最大值,如果不是,则必然在这个位置失序。同理,从后向前扫描,如果当前数在其位,则必然当前数是后面数的最小值。
需要注意的是,记录的两个位置,最大值失序位置是小于最小值失序位置的。
代码如下:

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int n=nums.length;
        int max=nums[0];
        int min=nums[n-1];
        int start=-2;
        int ed=-1;
        for(int i=1;i<n;i++)
        {
            if(max<nums[i])
                max=nums[i]; 
            else
                ed=i;
            if(min>nums[n-1-i])
                min=nums[n-1-i];
            else
                start=n-1-i;
        }
        return ed-start+1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值