画图画图画图 重要的事情说三遍
//max No. balls/bag 1 2 3 4
//balls in bag
2 1 0 0 0
4 3 1 1 0
8 7 3 2 1
2 1 0 0 0
maxOperations(newbags) 12 4 3 1
这么一看就不用说了 - 方法就是二分了。
这个图中左边是初始时包里面球的个数 比如有4个包,每个包里是2, 4, 8 , 2 个球
如果每个包里最多有2个球。
我们要操作几步哪?
比如有8个球, 每个包里最多2个球。 那我们要找3个袋子, 每个里放两个。这样最初的8个球的大袋子里最后就剩了2个。 这样就完成任务。
感觉这个问题可以转换成找袋子
也就是 nums / ballsPerBag - 1
但是这个公式也有个特殊的
17个球, 每个最多7个。 17 / 7 = 2.
整除完后还剩下3个球, 这些球还得要个袋子。
所以步骤的个数分为两个公式:
// nums % ballsPerBag == 0 => nums / ballsPerBag - 1;
// nums % ballsPerBag != 0 => nums / ballsPerBag;
class Solution {
public:
int calcMaxOperations(vector<int>& nums,int ballsPerBag)
{
int ret = 0;
if(ballsPerBag == 0)
return 0;
for(int num: nums) {
if(num % ballsPerBag == 0)
ret += num / ballsPerBag - 1;
else
ret += num / ballsPerBag;
}
return ret;
}
int minimumSize(vector<int>& nums, int maxOperations) {
// 画图 画图 画图 重要的事情说三遍
//max No. balls/bag 1 2 3 4
//balls in bag
// 2 1 0 0 0
// 4 3 1 1 0
// 8 7 3 2 1
// 2 1 0 0 0
//maxOperations 12 4 3 1
//这个图中左边是初始时包里面球的个数 比如有4个包,每个包里是2, 4, 8 , 2 个球
//如果每个包里最多有2个球。
//我们要操作几步哪?
//比如有8个球, 每个包里最多2个球。 那我们要找3个袋子, 每个里放两个。这样8个球的大袋子里最后就剩了2个。
//也就是 nums / ballsPerBag - 1
// 但是这个公式也有个特殊的
// 17个球, 每个最多7个。 17 / 7 = 2.
// 整除完后还剩下3个球, 这些球还得要个袋子。
// 所以步骤的个数分为两个公式:
// nums % ballsPerBag == 0 => ums / ballsPerBag - 1;
// nums % ballsPerBag != 0 => ums / ballsPerBag;
int start = 1;
int end = 0;
for(int num: nums) {
end = max(end, num);
}
while(start + 1 < end) {
int mid = start + (end - start) / 2;
int maxOper = calcMaxOperations(nums, mid);
if( maxOper > maxOperations)
start = mid;
else
end = mid;
}
if(calcMaxOperations(nums, start) <= maxOperations)
return start;
if(calcMaxOperations(nums, end) <= maxOperations)
return end;
return -1;
}
};
本文介绍如何通过二分查找算法解决分包问题,涉及将球分配到容量有限的包中,确保每包不超过最大容量,同时计算最小操作次数。核心公式和特殊情形的处理被详细阐述。
359

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



