---
# System prepended metadata

title: 0581. Shortest Unsorted Continuous Subarray
tags: [Leetcode, Sorting, Medium, Greedy, Stack]

---

# 0581. Shortest Unsorted Continuous Subarray
###### tags: `Leetcode` `Medium` `Stack` `Greedy` `Sorting`
Link: https://leetcode.com/problems/shortest-unsorted-continuous-subarray/
## 思路 
### 思路一 $O(N)$ $O(1)$
非常直觉的解法
首先先找递减序列确定边界 [minIdx, maxIdx]，因为递减序列无论如何都会要包含在要sort的subarray里面
然后找到这个subarray里面的最大和最小值 [minVal, maxVal]
再从[0, minIdx)里面找看有没有大于minVal的值，如果有左边界变成那个idx
再从(maxIdx, nums.length)里面倒序找看有没有小于maxVal的值，如果有有边界变成那个idx

### 思路二 $O(N)$ $O(1)$
更简单的思路 速度也更快
简单来说 对于每一个元素都要看前面有没有元素比它大，后面有没有元素比它小
所以遍历两次 
第一次正序 一直记录前面的最大值 如果最大值比现在元素大，就要记录位置
第二次倒序 一直记录前面的最小值 如果最小值比现在元素小，就要记录位置

### 思路三 stack $O(N)$ $O(N)$
## Code
### 思路一
```java=
class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int minIdx = Integer.MAX_VALUE;
        int maxIdx = Integer.MIN_VALUE;
        
        for(int i = 0;i < nums.length-1;i++){
            if(nums[i] > nums[i+1]){
                minIdx = Math.min(minIdx, i);
                maxIdx = Math.max(maxIdx, i+1);
            }
        }
        
        if(minIdx == Integer.MAX_VALUE) return 0;
        
        int minVal = Integer.MAX_VALUE;
        int maxVal = Integer.MIN_VALUE;
        for(int i = minIdx;i <= maxIdx;i++){
            minVal = Math.min(minVal, nums[i]);
            maxVal = Math.max(maxVal, nums[i]);
        }
        
        int l=minIdx, r=maxIdx;
        for(int i = 0;i < minIdx;i++){
            if(nums[i] > minVal){
                l = i;
                break;
            }
        }
        for(int i = nums.length-1;i > maxIdx;i--){
            if(nums[i] < maxVal){
                r = i;
                break;
            }
        }
        return r-l+1;
    }
}
```
### 思路二
```java=
class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int n = nums.length;
        int right = 0, max = nums[0];
        int left = n-1, min = nums[n-1];
        for(int i=0; i<n; i++){
            if(nums[i]<max) right = i;
            else max = nums[i];
        }
        for(int i=n-1; i>=0; i--){
            if(nums[i]>min) left = i;
            else min = nums[i];
        }
        return right>left?right-left+1:0;
    }
}
```
### 思路三
```java=
class Solution {
    public int findUnsortedSubarray(int[] nums) {
        Stack<Integer> stack = new Stack<>();
        int left = nums.length-1;
        for(int i = 0;i < nums.length;i++){
            while(!stack.isEmpty() && nums[stack.peek()]>nums[i]){
                left = Math.min(left, stack.pop());
            }
            stack.push(i);
        }
        int right = 0;
        stack = new Stack<>();
        for(int i = nums.length-1;i >= 0;i--){
            while(!stack.isEmpty() && nums[stack.peek()]<nums[i]){
                right = Math.max(right, stack.pop());
            }
            stack.push(i);
        }
        if(left<right) return right-left+1;
        else return 0;
    }
}
```