题目
给你一个整数数组 nums ,其中 nums[i] 表示第 i 个袋子里球的数目。同时给你一个整数 maxOperations 。
你可以进行如下操作至多 maxOperations 次:
- 选择任意一个袋子,并将袋子里的球分到 2 个新的袋子中,每个袋子里都有正整数个球。
- 比方说,一个袋子里有
5个球,你可以把它们分到两个新袋子里,分别有1个和4个球,或者分别有2个和3个球。
- 比方说,一个袋子里有
你的开销是单个袋子里球数目的 最大值 ,你想要 最小化 开销。
请你返回进行上述操作后的最小开销。
示例 1:
输入:nums = [9], maxOperations = 2
输出:3
解释:
- 将装有 9 个球的袋子分成装有 6 个和 3 个球的袋子。[9] -> [6,3] 。
- 将装有 6 个球的袋子分成装有 3 个和 3 个球的袋子。[6,3] -> [3,3,3] 。
装有最多球的袋子里装有 3 个球,所以开销为 3 并返回 3 。
示例 2:
输入:nums = [2,4,8,2], maxOperations = 4
输出:2
解释:
- 将装有 8 个球的袋子分成装有 4 个和 4 个球的袋子。[2,4,8,2] -> [2,4,4,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,4,4,4,2] -> [2,2,2,4,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,2,2,4,4,2] -> [2,2,2,2,2,4,2] 。
- 将装有 4 个球的袋子分成装有 2 个和 2 个球的袋子。[2,2,2,2,2,4,2] -> [2,2,2,2,2,2,2,2] 。
装有最多球的袋子里装有 2 个球,所以开销为 2 并返回 2 。
示例 3:
输入:nums = [7,17], maxOperations = 2
输出:7
提示:
1 <= nums.length <= 1051 <= maxOperations, nums[i] <= 109
分析
二分搜索
- 二分求拆分后的的袋子里的球数的最大值;
- 二分采用双闭区间写法;
- 初始值为:
0和int[] max;
条件判断
- 二分的判断主要是按照
mid(袋中最大球数)拆分是否满足maxOperations的最大拆分次数;- 满足往小调整;反之往大调整;
注意考虑:
拆分的袋子个数为:
k = [x/m]拆分次数为
k-1;
code
class Solution {
static int maxO;
public int minimumSize(int[] nums, int maxOperations) {
maxO = maxOperations;
return binarySearch(nums);
}
public boolean Judge(int[] nums, int x) {
if (x == 0)
return false;
long cnt = 0;
for (int num : nums) {
cnt += (num - 1) / x; // 原先包含一个袋子
}
return cnt <= maxO;
}
public int binarySearch(int[] nums) {
int l = 0, r = Arrays.stream(nums).max().getAsInt();
while (l <= r) {
int mid = l + (r - l) / 2;
if (Judge(nums, mid))
r = mid - 1;
else
l = mid + 1;
}
return l;
}
}
求数组中的最大值stream方法:
Arrays.stream(nums).max().getAsInt();
2194

被折叠的 条评论
为什么被折叠?



