【每日算法Day 88】超越妹妹教你如何做這道排序題

v2-88342ce402c1c7e14e37e465ec411668_b.jpg
每日一圖:我老婆可愛不?

題目鏈接

LeetCode 面試題 16.16. 部分排序[1]

題目描述

給定一個整數數組,編寫一個函數,找出索引 mn,只要將索引區間 [m, n] 的元素排好序,整個數組就是有序的。注意:n-m 儘量最小,也就是說,找出符合條件的最短序列。函數返回值爲 [m, n],若不存在這樣的 mn(例如整個數組是有序的),請返回 [-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. 部分排序: leetcode-cn.com/problem

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章