题目:
给定一个数组 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]
解题思路:
- 保证 left 中的最大值 <= right 中的最小值。设置两个指针 lidx 和 ridx,保证
lidx <= ridx
。设置局部最大值 localMax 和 临时局部最大值 localTempMax。然后遍历整个数组。 - 如果
nums[ridx] >= localMax
,那么我们先保存一个临时最大值 localTempMax,因为如果后面有小于 localMax 的值时,需要更新局部最大值。然后右指针继续右移一位。 - 如果
nums[ridx] < localMax
,说明又找到了一个比当前局部最大值小的值,则需要加入left。同时,局部最大值要更新为当前位置前所有元素中的最大值,也就是localTempMax。左指针直接移到当前位置,右指针继续右移一位。 - 遍历完整个数组后,左指针所在的位置之前的元素都小于等于右遍的元素。返回 lidx+1。(因为求的是长度,而lidx是从0开始的下标。)
/**
* @param {number[]} nums
* @return {number}
*/
var partitionDisjoint = function(nums) {
let lidx = 0, ridx = 1;
let localMax = nums[0];
let localTempMax = nums[1];
while(ridx < nums.length && lidx <= ridx){
if(nums[ridx] >= localMax){
localTempMax = Math.max(localTempMax, nums[ridx])
ridx++;
}else{
localMax = Math.max(localMax, localTempMax);
lidx = ridx;
ridx++;
}
}
return lidx + 1;
};