题目所属分类
分类的话 算 双指针算法吧
原题链接
给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
请你找出符合题意的 最短 子数组,并输出它的长度。
代码案例:输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
题解
找到两段已经排好序的长度。我们先使用一遍扫描找到左边保持升序的最后一个点的位置left,和从右向左看保持降序的最后一个点的位置right。如果已经这时候left == right
说明已经排好序了,无需调整。接下来我们从left + 1的位置向右扫描,如果遇到有比nums[left]小的元素,说明最起码left不在正确位置上,那么left —。同样的,我们从right - 1的位置向左扫描,如果遇到有比nums[right]大的元素,说明最起码nums[right]不在正确的位置上,right ++。最后,left和right之间的元素就是需要重新排序的元素,长度为right - left - 1。
时间复杂度O(n) 空间复杂度O(1) 。
class Solution {
public int findUnsortedSubarray(int[] nums) {
int n = nums.length ; int left = 0 ; int right = n - 1;
if(n == 1)return 0 ;
while(left < n-1 && nums[left+1] >= nums[left]) left++;
while(right > left && nums[right] >= nums[right - 1])right-- ;
if(left == right) return 0 ;
for(int i = left + 1 ;i < n ; i ++){
while(left >= 0 && nums[i] < nums[left])left--;
}
for(int i = right-1 ; i>= 0 ; i--){
while(right <= n -1 && nums[i] > nums[right]) right++;
}
return right - left-1;
}
}