<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)