<br> Given an array `A`, partition it into two (contiguous) subarrays `left` and `right` so that:html
- Every element in
left
is less than or equal to every element inright
. left
andright
are non-empty.left
has the smallest possible size.
Return the length of left
after such a partitioning. It is guaranteed that such a partitioning exists.git
Example 1:github
Input: [5,0,3,8,6] Output: 3 Explanation: left = [5,0,3], right = [8,6]
Example 2:數組
Input: [1,1,1,0,6,12] Output: 4 Explanation: left = [1,1,1,0], right = [6,12]
Note:less
2 <= A.length <= 30000
0 <= A[i] <= 10^6
- It is guaranteed there is at least one way to partition
A
as described.
<br> 這道題說是給了一個數組A,讓咱們分紅兩個相鄰的子數組 left 和 right,使得 left 中的全部數字小於等於 right 中的,並限定了每一個輸入數組一定會有這麼一個分割點,讓返回數組 left 的長度。這道題並不算一道難題,固然最簡單並暴力的方法就是遍歷全部的分割點,而後去驗證左邊的數組是否都小於等於右邊的數,這種寫法估計會超時,這裏就不去實現了。直接來想優化解法吧,因爲分割成的 left 和 right 數組自己不必定是有序的,只是要求 left 中的最大值要小於等於 right 中的最小值,只要這個條件知足了,必定就是符合題意的分割。left 數組的最大值很好求,在遍歷數組的過程當中就能夠獲得,而 right 數組的最小值怎麼求呢?其實能夠反向遍歷數組,而且使用一個數組 backMin,其中 backMin[i] 表示在範圍 [i, n-1] 範圍內的最小值,有了這個數組後,再正向遍歷一次數組,每次更新當前最大值 curMax,這就是範圍 [0, i] 內的最大值,經過 backMin 數組快速獲得範圍 [i+1, n-1] 內的最小值,假如 left 的最大值小於等於 right 的最小值,則 i+1 就是 left 的長度,直接返回便可,參見代碼以下:優化
<br> 解法一:url
class Solution { public: int partitionDisjoint(vector<int>& A) { int n = A.size(), curMax = INT_MIN; vector<int> backMin(n, A.back()); for (int i = n - 2; i >= 0; --i) { backMin[i] = min(backMin[i + 1], A[i]); } for (int i = 0; i < n - 1; ++i) { curMax = max(curMax, A[i]); if (curMax <= backMin[i + 1]) return i + 1; } return 0; } };
<br> 下面來看論壇上的主流解法,只須要一次遍歷便可,而且不須要額外的空間,這裏使用三個變量,partitionIdx 表示分割點的位置,preMax 表示 left 中的最大值,curMax 表示當前的最大值。思路是遍歷每一個數字,更新當前最大值 curMax,而且判斷若當前數字 A[i] 小於 preMax,說明這個數字也必定是屬於 left 數組的,此時整個遍歷到的區域應該都是屬於 left 的,因此 preMax 要更新爲 curMax,而且當前位置也就是潛在的分割點,因此 partitionIdx 更新爲i。因爲題目中限定了必定會有分割點,因此這種方法是能夠獲得正確結果的,參見代碼以下:.net
<br> 解法二:code
class Solution { public: int partitionDisjoint(vector<int>& A) { int partitionIdx = 0, preMax = A[0], curMax = preMax; for (int i = 1; i < A.size(); ++i) { curMax = max(curMax, A[i]); if (A[i] < preMax) { preMax = curMax; partitionIdx = i; } } return partitionIdx + 1; } };
<br> Github 同步地址:htm
https://github.com/grandyang/leetcode/issues/915
<br> 參考資料:
https://leetcode.com/problems/partition-array-into-disjoint-intervals/
<br> [LeetCode All in One 題目講解彙總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)