【刷题】410. 分割数组的最大值
程序员文章站
2022-07-01 17:17:03
...
题目:
给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。
注意:
数组长度 n 满足以下条件:
1 ≤ n ≤ 1000
1 ≤ m ≤ min(50, n)
方法一:二分法
由题意可知:子数组的最大值是有范围的,即在区间 [nums的最大元素值,nums的元素之和]之中。
令 left=nums的最大元素值,right=nums的元素之和,mid=(left+right)/2.计算数组和最大值不大于mid对应的子数组个数 cnt(这个是关键!)
如果 cnt>m,说明划分的子数组多了,即我们找到的 mid 偏小,故 left=mid+1;
否则,说明划分的子数组少了,即 mid 偏大(或者正好就是目标值),故right=mid。
public int splitArray(int[] nums, int m) {
int left = 0, right = 0;
for (int i = 0; i < nums.length; i++) {
right += nums[i];//求和
if (left < nums[i]) {
left = nums[i];//找nums的最大元素
}
}
while (left < right) {
int mid = (right - left) / 2 + left;
if (check(nums, mid, m)) {//查看mid是否满足条件,当right=left的时候就跳出循环了
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
public boolean check(int[] nums, int x, int m) {
int sum = 0;
int cnt = 1;
for (int i = 0; i < nums.length; i++) {
if (sum + nums[i] > x) {
cnt++;
sum = nums[i];
} else {
sum += nums[i];
}
}
return cnt <= m;
}
、
上一篇: Socket通信——同步通信
下一篇: 帮你正确认识针灸减肥原理