581. Shortest Unsorted Continuous Subarray

问题:

求数列中最小的未排序子数列(即,如果将此子数列排序后,整个数列则成为有序数列)

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.

  

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

  

解法一:sort+对比法

1. 首先copy到新的数列,并sort

[2, 4, 6, 3, 14, 10, 13, 15]
->
[2, 3, 4, 6, 10, 13, 14, 15]
 0  1  2  3  4   5   6   7
    ^                ^
   Start            End

  

2. 顺次对比两个数列

3. 得到两个数列不相等元素的Start和End

则所求长度为End-Start+1

代码参考:

 1 class Solution {
 2 public:
 3     int findUnsortedSubarray(vector<int>& nums) {
 4         vector <int> sortednums(nums);
 5         sort(sortednums.begin(), sortednums.end());
 6         int start = nums.size()-1, end = 0;
 7         for(int i = 0; i<nums.size(); i++){
 8             if(sortednums[i]!=nums[i]){
 9                 start = min(start, i);
10                 end = max(end, i);
11             }
12         }
13         return (end-start > 0? end-start+1:0);
14     }
15 };

解法二:

 例如:

[2, 4, 6, 3, 14, 10, 13, 15]
 0  1  2  3  4   5   6   7
       ^         ^ 

 1.先从两端取得顺序排列的[0~i]和[j~end]

[2,4,6]    -> i=2   (0~i  递增)
[10,13,15] -> j=5   (j~end递增)

 2.对于余下的数列 [3,14],取得最大值,和最小值

min = 3
max = 14

 3.使用2中取得最大值最小值,向两侧推移,找到 向左<min 和 向右>max的边界【i,j】。 

[2,4,6]    -> i=0   (2<3<4)
 ^
[10,13,15] -> j=7   (13<14<15)
       ^

  

则,[4,6,....,10,13]为所求最小子数列,长度为:j-i-1=7-0-1=6

代码参考:

 1 class Solution {
 2 public:
 3     int findUnsortedSubarray(vector<int>& nums) {
 4         int i=0, j=nums.size()-1;
 5         while(i<nums.size()-1){
 6             if(nums[i]>nums[i+1])break;
 7             i++;
 8         }
 9         if(i>=j) return 0;
10         while(j>0){
11             if(nums[j]<nums[j-1])break;
12             j--;
13         }
14         int maxN=INT_MIN, minN=INT_MAX;
15         for(int k=i; k<=j; k++){
16             maxN=max(maxN, nums[k]);
17             minN=min(minN, nums[k]);
18         }
19         while(i>=0){
20             if(nums[i]>minN)i--;
21             else {break;}
22         }
23         while(j<nums.size()){
24             if(nums[j]<maxN)j++;
25             else {break;}
26         }
27         return j-i-1;
28     }
29 };
原文地址:https://www.cnblogs.com/habibah-chang/p/12442312.html