题目
给定一个数组 nums
,将其划分为两个连续子数组 left
和 right
, 使得:
left
中的每个元素都小于或等于right
中的每个元素。left
和right
都是非空的。left
的长度要尽可能小。
在完成这样的分组后返回 left
的 长度 。
用例可以保证存在这样的划分方法。
示例 1:
输入:nums = [5,0,3,8,6]
输出:3
解释:left = [5,0,3],right = [8,6]
示例 2:
输入:nums = [1,1,1,0,6,12]
输出:4
解释:left = [1,1,1,0],right = [6,12]
提示:
2 <= nums.length <= 10^5
0 <= nums[i] <= 10^6
- 可以保证至少有一种方法能够按题目所描述的那样对
nums
进行划分。
解题
方法一:三次遍历
思路
代码
class Solution {
public int partitionDisjoint(int[] nums) {
int n = nums.length;
int[] leftMax = new int[n], rightMin = new int[n];
leftMax[0] = nums[0];
rightMin[n - 1] = nums[n - 1];
for (int i = 1, j = n - 2; i < n; ++i, j = n - i - 1) {
leftMax[i] = Math.max(leftMax[i - 1], nums[i]);
rightMin[j] = Math.min(rightMin[j + 1], nums[j]);
}
for (int i = 0; i < n - 1; ++i) {
if (leftMax[i] <= rightMin[i + 1]) return i + 1;
}
return -1;
}
}
方法二:两次遍历
思路
代码
class Solution {
public int partitionDisjoint(int[] nums) {
int n = nums.length;
int[] mins = new int[n];
mins[n - 1] = nums[n - 1];
for (int i = n - 2; i >= 0 ; --i) mins[i] = Math.min(mins[i + 1], nums[i]);
for (int i = 0, max = nums[0]; i < n - 1; max = Math.max(max, nums[++i])) {
if (max <= mins[i + 1]) return i + 1;
}
return -1;
}
}
方法三:一次遍历
思路
代码
评论区