letecode [581] - Shortest Unsorted Continuous Subarray

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 <=.

题目大意

  给定一个数组,对它的子数组排序使得数组元素递增,求最小子数组长度。

理  解:

  看的其他人的方法。 

  方法一:copy原数组,排序,找到排序数组与原数组首位第一个不同的位置i,j,两位置间的元素即为子数组,子数组长度=j - i + 1。

      时间复杂度O(nlogn),空间复杂度O(n).

  方法二:在线性时间内实现。

      1. 从左往右找到第一个小于左值的位置st,即nums[st] >nums[st+1];

      2. 从右往左找到第一个大于右值的位置ed,即nums[ed] < nums[ed-1];

      3. 由于子数组要满足,其最小值大于左部分,其最大值小于右部分。

      4. 在[st,nums.size()-1]中找到最小值min;在[0,ed]中找到最大值max;

      5. 判断min的位置,若min在[0,st]中,找到该位置newst;

       判断max的位置,若max在[ed,nums.size()-1]中,找到该位置newed;

代 码 C++:

方法一:

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        vector<int> copy;
        copy.assign(nums.begin(),nums.end());
        sort(copy.begin(),copy.end());
        int i=0,j=nums.size()-1;
        while(i<=j && copy[i]==nums[i]) ++i;
        while(j>=i && copy[j]==nums[j]) --j;
        return (j-i+1);
    }
};

方法二:

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        if(nums.size()==0) return 0;
        int st = nums.size()-1 ,ed = -1,max=INT_MIN,min=INT_MAX;
        for(int i=0;i<nums.size()-1;++i){
            if(nums[i]>nums[i+1]){
                st = i+1;
                break;
            }
        }
        for(int i=nums.size()-1;i>0;--i){
            if(nums[i]<nums[i-1]){
                ed = i-1;
                break;
            }
        }
        
        for(int i=0;i<=ed;++i){
            if(nums[i]>max)
                max = nums[i];
        }
        
        for(int i=st;i<nums.size();++i){
            if(nums[i]<min)
                min = nums[i];
        }
        for(int i=0;i<st;++i){
            if(nums[i]>min)
            {
                st = i;
                break;
            }
        }
        for(int i=nums.size()-1;i>ed;i--){
            if(nums[i]<max)
            {
                ed = i;
                break;
            }
        }
       // cout<<ed<<" "<<st;
        return ed-st+1>0? (ed-st+1):0;
    }
};

运行结果:

  方法一:执行用时 :56 ms, 在所有 C++ 提交中击败了55.98%的用户

      内存消耗 :11.2 MB, 在所有 C++ 提交中击败了79.86%的用户

  方法二:执行用时 :52 ms, 在所有 C++ 提交中击败了64.26%的用户

      内存消耗 :10.6 MB, 在所有 C++ 提交中击败了84.89%的用户
posted @ 2019-07-09 21:03  lpomeloz  阅读(178)  评论(0编辑  收藏  举报