持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情
刷题的日常-2022年10月24号
一天一题,保持脑子清爽
分割数组
来自leetcode的 915 题,题意如下:
给定一个数组nums,将其划分为两个连续子数组left和right,使得:
- left中的每个元素都小于或等于right中的每个元素。
- left 和right都是非空的。
- left 的长度要尽可能小。
在完成这样的分组后返回left的长度。
用例可以保证存在这样的划分方法。
理解题意
通过题意,我们可以将信息整理如下:
- 题目给出一个数组
- 要求我们对数组分成两个部分
- 第二部分所有的数字 要大于等于 第一部分的所有数值
- 返回第一部分的大小
做题思路
要让左边的数 小于等于 第二部分的数,那么数组里的最小值一定要划分在第一部分,所以我们要先找出最小值位置。以最小值的位置作为划分,分出左右两个部分,这个时候我们还需要检查划分出来的两个部分中,第二部分 有没有比 第一部分的最大值还要小的值,如果有,还要将当前值作为划分才能满足需求,步骤如下:
- 先找出最小值的分界线
- 寻找的过程中顺便记录最小值分界线的最大值
- 找出最小值分界线之后,以分界线为开始往后扫描
- 找出比分界线左边最大值还要小的值
- 找到之后作为新的分界点,在这过程中也需要更新分界线的最大值
- 重复以上步骤知道数组最后
- 返回分界点 + 1即为结果
代码实现
代码实现如下:
public class Solution {
public int partitionDisjoint(int... nums) {
int post = nums.length - 1;
int min = 0, max = 0, minMax = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] < nums[min]) {
minMax = max;
}
min = nums[i] < nums[min] ? i : min;
max = nums[max] < nums[i] ? i : max;
}
max = minMax;
for (int i = min; i < nums.length; i++) {
max = nums[max] < nums[i] ? i : max;
if (nums[i] >= nums[minMax]) {
continue;
}
max = nums[max] < nums[i] ? i : max;
minMax = max;
min = i;
}
return min + 1;
}
}