---
comments: true
difficulty: 中等
edit_url: https://github.com/doocs/leetcode/edit/main/lcci/16.16.Sub%20Sort/README.md
---

<!-- problem:start -->

# [面试题 16.16. 部分排序](https://leetcode.cn/problems/sub-sort-lcci)

[English Version](/lcci/16.15.Master%20Mind/README_EN.md)

## 题目描述

<!-- description:start -->

<p>给定一个整数数组,编写一个函数,找出索引<code>m</code>和<code>n</code>,只要将索引区间<code>[m,n]</code>的元素排好序,整个数组就是有序的。注意:<code>n-m</code>尽量最小,也就是说,找出符合条件的最短序列。函数返回值为<code>[m,n]</code>,若不存在这样的<code>m</code>和<code>n</code>(例如整个数组是有序的),请返回<code>[-1,-1]</code>。</p>
<p><strong>示例:</strong></p>
<pre><strong>输入:</strong> [1,2,4,7,10,11,7,12,6,7,16,18,19]
<strong>输出:</strong> [3,9]
</pre>
<p><strong>提示:</strong></p>
<ul>
<li><code>0 <= len(array) <= 1000000</code></li>
</ul>

<!-- description:end -->

## 解法

<!-- solution:start -->

### 方法一:两次遍历

我们先从左到右遍历数组 $array$,用 $mx$ 记录遍历过的最大值,如果当前值 $x$ 小于 $mx$,则说明 $x$ 需要被排序,我们将 $x$ 的下标 $i$ 记录为 $right$;否则更新 $mx$。

同理,我们再从右到左遍历数组 $array$,用 $mi$ 记录遍历过的最小值,如果当前值 $x$ 大于 $mi$,则说明 $x$ 需要被排序,我们将 $x$ 的下标 $i$ 记录为 $left$;否则更新 $mi$。

最后返回 $[left, right]$ 即可。

时间复杂度 $O(n)$,其中 $n$ 为数组长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

#### Python3

```python
class Solution:
    def subSort(self, array: List[int]) -> List[int]:
        n = len(array)
        mi, mx = inf, -inf
        left = right = -1
        for i, x in enumerate(array):
            if x < mx:
                right = i
            else:
                mx = x
        for i in range(n - 1, -1, -1):
            if array[i] > mi:
                left = i
            else:
                mi = array[i]
        return [left, right]
```

#### Java

```java
class Solution {
    public int[] subSort(int[] array) {
        int n = array.length;
        int mi = Integer.MAX_VALUE, mx = Integer.MIN_VALUE;
        int left = -1, right = -1;
        for (int i = 0; i < n; ++i) {
            if (array[i] < mx) {
                right = i;
            } else {
                mx = array[i];
            }
        }
        for (int i = n - 1; i >= 0; --i) {
            if (array[i] > mi) {
                left = i;
            } else {
                mi = array[i];
            }
        }
        return new int[] {left, right};
    }
}
```

#### C++

```cpp
class Solution {
public:
    vector<int> subSort(vector<int>& array) {
        int n = array.size();
        int mi = INT_MAX, mx = INT_MIN;
        int left = -1, right = -1;
        for (int i = 0; i < n; ++i) {
            if (array[i] < mx) {
                right = i;
            } else {
                mx = array[i];
            }
        }
        for (int i = n - 1; ~i; --i) {
            if (array[i] > mi) {
                left = i;
            } else {
                mi = array[i];
            }
        }
        return {left, right};
    }
};
```

#### Go

```go
func subSort(array []int) []int {
	n := len(array)
	mi, mx := math.MaxInt32, math.MinInt32
	left, right := -1, -1
	for i, x := range array {
		if x < mx {
			right = i
		} else {
			mx = x
		}
	}
	for i := n - 1; i >= 0; i-- {
		if array[i] > mi {
			left = i
		} else {
			mi = array[i]
		}
	}
	return []int{left, right}
}
```

#### TypeScript

```ts
function subSort(array: number[]): number[] {
    const n = array.length;
    let [mi, mx] = [Infinity, -Infinity];
    let [left, right] = [-1, -1];
    for (let i = 0; i < n; ++i) {
        if (array[i] < mx) {
            right = i;
        } else {
            mx = array[i];
        }
    }
    for (let i = n - 1; ~i; --i) {
        if (array[i] > mi) {
            left = i;
        } else {
            mi = array[i];
        }
    }
    return [left, right];
}
```

#### Swift

```swift
class Solution {
    func subSort(_ array: [Int]) -> [Int] {
        let n = array.count
        var mi = Int.max, mx = Int.min
        var left = -1, right = -1

        for i in 0..<n {
            if array[i] < mx {
                right = i
            } else {
                mx = array[i]
            }
        }

        for i in stride(from: n - 1, through: 0, by: -1) {
            if array[i] > mi {
                left = i
            } else {
                mi = array[i]
            }
        }

        return [left, right]
    }
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->