題目鏈接
LeetCode 面試題 16.16. 部分排序[1]
題目描述
給定一個整數數組,編寫一個函數,找出索引 m
和 n
,只要將索引區間 [m, n]
的元素排好序,整個數組就是有序的。注意:n-m
儘量最小,也就是說,找出符合條件的最短序列。函數返回值爲 [m, n]
,若不存在這樣的 m
和 n
(例如整個數組是有序的),請返回 [-1, -1]
。
示例1
輸入:
[1,2,4,7,10,11,7,12,6,7,16,18,19]
輸出:
[3,9]
說明:
-
0 <= len(array) <= 1000000
題解
首先雖然題目沒說,但是實際運行下來數列是單調遞增的,所以我們下面默認數列是遞增的。
那麼對於元素 a[i]
來說,如果它左邊存在大於 a[i]
的元素,那麼 a[i]
是一定要參與到排序裏去的。或者說如果它右邊存在小於 a[i]
的元素,那麼 a[i]
也是要參與到排序裏去的。
所以我們只需要尋找最靠右的那個數(滿足左邊存在大於它的數),和最靠左的那個數(滿足右邊存在小於它的數),那麼這兩個數之間就是要排序的區間了。
爲什麼最靠右的那個(滿足左邊存在大於它的數)數一定能保證右邊沒有更小的數了呢?因爲如果右邊還有更小的數,那麼那個更小的數纔是更靠右的啊,這就矛盾了。
所以我們只需要從左到右掃描一遍,用一個變量維護一下最大值就行了,然後反向再遍歷一遍,維護一個最小值。
代碼
c++
class Solution {
public:
vector<int> subSort(vector<int>& array) {
int n = array.size();
int maxx = INT_MIN, minn = INT_MAX;
int l = -1, r = -1;
for (int i = 0; i < n; ++i) {
if (array[i] < maxx) r = i;
else maxx = array[i];
}
for (int i = n-1; i >= 0; --i) {
if (array[i] > minn) l = i;
else minn = array[i];
}
return {l, r};
}
};
python
class Solution:
def subSort(self, array: List[int]) -> List[int]:
n = len(array)
maxx, minn = -10000000, 10000000
l, r = -1, -1
for i in range(n):
if array[i] < maxx: r = i
else: maxx = array[i]
for i in range(n-1, -1, -1):
if array[i] > minn: l = i
else: minn = array[i]
return [l, r]
關注【算法碼上來】,每日算法乾貨馬上就來!
參考資料
[1]
LeetCode 面試題 16.16. 部分排序: https://leetcode-cn.com/problems/sub-sort-lcci/