0915. 分割数组【中等】
1. 📝 题目描述
给定一个数组 nums,将其划分为两个连续子数组 left 和 right, 使得:
left中的每个元素都小于或等于right中的每个元素。left和right都是非空的。left的长度要尽可能小。
在完成这样的分组后返回 left 的 长度。
用例可以保证存在这样的划分方法。
示例 1:
txt
输入:nums = [5,0,3,8,6]
输出:3
解释:left = [5,0,3],right = [8,6]1
2
3
2
3
示例 2:
txt
输入:nums = [1,1,1,0,6,12]
输出:4
解释:left = [1,1,1,0],right = [6,12]1
2
3
2
3
提示:
2 <= nums.length <= 10^50 <= nums[i] <= 10^6- 可以保证至少有一种方法能够按题目所描述的那样对
nums进行划分。
2. 🎯 s.1 - 一次遍历
js
/**
* @param {number[]} nums
* @return {number}
*/
var partitionDisjoint = function (nums) {
let leftMax = nums[0]
let curMax = nums[0]
let partitionIdx = 0
for (let i = 1; i < nums.length; i++) {
if (nums[i] < leftMax) {
partitionIdx = i
leftMax = curMax
} else {
curMax = Math.max(curMax, nums[i])
}
}
return partitionIdx + 1
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 时间复杂度:
,其中 n 是数组长度 - 空间复杂度:
,只使用常数额外空间
算法思路:
- 维护
leftMax(左部分最大值)、curMax(当前全局最大值)以及分割点索引partitionIdx - 遍历数组,如果当前元素小于
leftMax,说明当前元素必须属于左部分,更新分割点并将leftMax更新为curMax - 否则更新
curMax - 返回
partitionIdx + 1