581. Shortest Unsorted Continuous Subarray

Problem statement:

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:

  1. Then length of the input array is in range [1, 10,000].
  2. The input array may contain duplicates, so ascending order here means <=.

Solution one:

As the first question of weekly contest 32, I spend 40 minutes to solve this problem. I know how to detect the end position of this subarray, we loop from front to end and record the max value, if the current element is less than max value, then mark it the end position. However, at that time I did not figure it out that we can loop from back to front to find the start position. This is why I spend so much time, and the corner cases are too many to test. 

The following is my first solution, it is an AC solution. I copied a new array and sort this array by ascending order and compare from front to find the start position and loop from back to find the end position.

It is tricky, initializing end = -2, so that even the array is already sorted by ascending order, we also can get the right solution.

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        vector<int> copy(nums.begin(), nums.end());
        sort(copy.begin(), copy.end());
        int size = nums.size();
        int left = 0;
        int right = size - 1;
        int start = -1;
        int end = -2;
        while(left < size){
            if(copy[left] == nums[left]){
                left++;
            } else {
                start = left;
                break;
            }
        }
        while(right >= 0){
            if(copy[right] == nums[right]){
                right--;
            } else {
                end = right;
                break;
            }
        }
        return end - start + 1;
    }
};

Solution two:

I can not sleep very well last night and even wake up until the sky is bright since I also dislike the solution one. Finally, figured it out at my bed that we can loop from back till front to find the start position. The time complexity is O(n), this is the best solution.

class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
        int max_val = INT_MIN;
        int min_val = INT_MAX;
        int size = nums.size();
        int start = -1;
        int end = -2;
        for(int i = 0; i < size; i++){
             // from left to right, find the position of end;
            if(nums[i] >= max_val){
                max_val = nums[i];
            } else {
                end = i;
            }
            // from right to left, find the position of start;
            if(nums[size - 1 - i] <= min_val){
                min_val = nums[size - 1 - i];
            } else {
                start = size - 1 - i;
            }
        }
        return end - start + 1;
    }
};
posted @ 2017-05-15 05:39  蓝色地中海  阅读(771)  评论(0编辑  收藏  举报