思路1:题目的意思是,将数组排序之后,有哪一些元素不会变动位置,因此比较直接的一种思路就是将数组排序,然后比较数组前段与后段相同的元素有哪些,统计即可。时间复杂度为O(nlogn),为了不改变原数组,需要另辟空间,空间复杂度为O(n)。
思路2:事实上,并不需要真的对数组进行排序,观察有以下结论:(1)从前向后元素应该是递增,即第i个元素应该是第0个元素~第i个元素的最大值,否则第i个元素递增逆序,记录递增逆序元素下标,遍历完成后,保留的应该是最后一个递增逆序元素下标,即无序段的右边界;(2)同样,从后向前类似,寻找到最后一个递减逆序元素下标。时间复杂度O(n),空间复杂度O(1)。
思路1解法:
public int findUnsortedSubarray(int[] nums) {
if(nums==null||nums.length==0) return -1;
//空间复杂度O(n)
int[] sortedNums=nums.clone();
int length=nums.length,index=0;
int antiAnswer=0;
//时间复杂度O(nlogn)
Arrays.sort(sortedNums);
for(;index<length;index++){
if(nums[index]!=sortedNums[index]){
break;
}
antiAnswer++;
}
for(int i=length-1;i>=index;i--){
if(nums[i]!=sortedNums[i]){
break;
}
antiAnswer++;
}
return length-antiAnswer;
}
思路2解法
public int findUnsortedSubarray(int[] nums) {
if (nums == null || nums.length == 0) return -1;
int max=Integer.MIN_VALUE,min=Integer.MAX_VALUE;
int length=nums.length;
int left=length,right=-1;
//记录两个值,一个是前面遍历元素的最大值,一个是最后出现逆序的位置
for(int i=0;i<length;i++){
if(nums[i]>=max){
max=nums[i];
}
else{
right=i;
}
}
for(int i=length-1;i>=0;i--){
if(nums[i]<=min){
min=nums[i];
}
else{
left=i;
}
}
//需要判断一下,避免原始数组有序出现异常
return right>=left?right-left+1:0;
}