16.Shortest Unsorted Continuous Subarray(最短未排序子数组)

Level:

  Easy

题目描述:

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(nlgn)。

  思路二:根据题意子数组的start和end需要满足的条件是,start-1后面的数都要比该点大,end+1前面的数都要比该点小。因此先找到第一个比start-1点小的数,然后搜索后面的数保证都比起大,遇见小的start往前移,同样的从先找到第一个比end+1点大的点,然后往前搜索如果有比他大的,则end+1要后移;

代码:

思路一:

class Solution {
     public int findUnsortedSubarray(int[] nums) {
         int i,j;
         int []temp=nums.clone();
         Arrays.sort(nums);
         for(i=0;i<nums.length;i++){
             if(nums[i]!=temp[i])
                break;         }
        for(j=nums.length-1;j>=0;j--){
             if(nums[j]!=temp[j])
                 break;
         }
         if(i==nums.length&&j==-1)
             return 0;
        
         else
             return j-i+1;
     }

思路二:

public class Solution{
    public int findUnsortedSubarray(int []nums){
        //先找start
        int pos=1;
        while(pos<nums.length&&nums[pos]>=nums[pos-1])
            pos++;
        if(pos==nums.length)//证明全部都是有序的
            return 0;
        int start=pos-1;
        while(pos<nums.length){
            while(start>=0&&nums[start]>nums[pos])//遇见后面比其小的start位置就得前移
                start--;
            if(start==-1)//子数组从第一个元素开始
                break;
            pos++;
        }
        //找end
        pos=nums.length-2;
        while(pos>=0&&nums[pos]<nums[pos+1])
            pos--;
        if(pos==-1)
            return 0;
        int end=pos+1;
        while(pos>=0){
            while(end<nums.length&&nums[end]<nums[pos])//遇见前面比其大的end位置就得后移
                end++;
            if(end==nums.length)
                break;
            pos--;
        }
        return end-start-1;
    }
}
原文地址:https://www.cnblogs.com/yjxyy/p/10720450.html