1. 程式人生 > >【LeetCode】581. Shortest Unsorted Continuous Subarray

【LeetCode】581. Shortest Unsorted Continuous Subarray

581. Shortest Unsorted Continuous Subarray

Description:
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.
Difficulty:Easy

,個人感覺難度 Medium
Example:

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

方法1:暴力求解,超時

  • Time complexity : O ( n 3 )
    O\left ( n^{3} \right )
  • Space complexity : O ( 1 ) O\left ( 1 \right )
    思路:
    1.考慮每個子陣列nums[i:j],求出子陣列的maxmin
    2.假設nums[0:i-1]nums[j:n-1]是有序的,nums[i:j]是亂序的,需要滿足nums[0:i-1]的元素都小於min以及nums[j:n-1]的元素都大於max,此時記錄j-i
    3.取最小的j-i
class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
		int n = nums.size();
		int res = n;
		for (int i = 0; i < n; i++) {
			for (int j = i; j <= n; j++) {
				int mins = INT_MAX, maxs = INT_MIN, prev = INT_MIN;
				for (int k = i; k < j; k++) {
					mins = min(mins, nums[k]);
					maxs = max(maxs, nums[k]);
				}
				if ((i > 0 && nums[i - 1] > mins) || (j < n && nums[j] < maxs)) 
					continue;
				int k = 0;
				while (k < i && prev <= nums[k]) {
					prev = nums[k];
					k++;
				}
				if (k != i)
					continue;
				k = j;
				while (k < n && prev <= nums[k]) {
					prev = nums[k];
					k++;
				}
				if (k == n) 
					res = min(res, j - i);
			}
		}
		return res;
    }
};

方法2:兩兩比較,差解

  • Time complexity : O ( n 2 ) O\left ( n^{2} \right )
  • Space complexity : O ( 1 ) O\left ( 1 \right )
    思路:
    1.每兩個元素進行比較,例如nums[i]nums[j]i<j<n,如果nums[j]>nums[i]說明這兩個元素亂序,記錄下左邊界和右邊界
    2.更新邊界時,取最左和最右
class Solution {
public:
    int findUnsortedSubarray(vector<int>& nums) {
		int n = nums.size();
		int left = n, right = 0;
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				if (nums[i] > nums[j]) {
					left = min(i, left);
					right = max(j, right);
				}
			}
		}
		return right - left < 0 ? 0 : right - left + 1;
    }
};