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:
- Then length of the input array is in range [1, 10,000].
- 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;
}
}