持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情
可恨的周一,又要开始一周的搬砖之旅了
分割数组
该题出自力扣的915题 —— 分割数组【中等题】,可恶的中等题
审题
给定一个数组 nums ,将其划分为两个连续子数组 left 和 right, 使得: left 中的每个元素都小于或等于 right 中的每个元素。 left 和 right 都是非空的。 left 的长度要尽可能小。 在完成这样的分组后返回 left 的 长度 。 用例可以保证存在这样的划分方法。
- 该题虽然是中等题,但是题意很好理解,就是看自己能不能转过弯来,给出一个整型数组,根据数组划分出两个区域,a区域内的数值要比b区域的小,并且a区域要尽可能的小
- 其实可以归纳为贪心的做法,判断的是a区域的最大值和b区域的最小值,至少需要一次遍历,并且不能用剪枝的方法,因为在后续的遍历仲会遇到更小的值,那就意味着需要更新a区域的最小值
- 定义三个变量
- ans:a区域的个数
- maxL:a区域的最大值
- cur:遍历过的最大值
- 遍历整个数组,每次与当前下标的值作最大值赋值到cur,判断当前的值是否小于maxL变量,如果是,则迭代maxL变量和ans下标
- 如果再次遇到比max小的值,那么左边数组不得不包含它,此时之前记录的值就应该作为max,因为此时左边数组的最大值已经变为了nums[i]。
- 使用两个数组分别记录从左往右的最大值以及从右往左的最小值,从头开始遍历当当前位置的左边最大值小于等于下一个位置的右边最小值时,则当前位置就是长度最小的答案。
编码
class Solution {
public int partitionDisjoint(int[] nums) {
int len = nums.length;
int ans = 0,maxL = nums[0],cur = nums[0];
for (int i = 1; i < len - 1; i++) {
cur = Math.max(cur,nums[i]);
if (maxL > nums[i]){
maxL = cur;
ans = i;
}
}
return ans + 1;
}
}