袋子里最少数目的球
思路
- 注意输入值范围 , 过大的范围所以暴力法是无解的, 且二维DP也不可能
1 <= nums.length <= 10^5
1 <= maxOperations, nums[i] <= 10^9
- 只需要求出操作后球最多的那一个袋子的个数, 而不在乎具体每个袋子里各有多少个球
- 总结: 对于求出完整解决方案非常困难的题目, 考虑是否真的有必要求出完整的解决方案
- 要点: 猜测一个 minimum 值, 验证达成这个值是否能够通过合法的操作达成
非常容易
- 思维转变: 求每个袋子怎么操作, 怎么分球, 最后剩的最多的球数 -> 直接猜测一个球数, 让所有袋子里的球都满足这个值, 反向计算需要的操作次数
- 结果:
二分查找
题解代码, 学习自 228 周赛冠军 arknave
class Solution
{
public:
int minimumSize(vector<int> &nums, int maxOperations)
{
// 标准二分查找的最小值和最大值
int minValue = 0;
int maxValue = 1e9 + 7;
// 该循环条件确保 mid> minValue, 即 minValue一定是非法的
while (minValue + 1 < maxValue)
{
// 二分查找
int mid = minValue + (maxValue - minValue) / 2;
// 计算需要的操作次数
long long opTimes = 0;
for (int x : nums)
{
opTimes += (x - 1) / mid;
}
// 如果合法
if (opTimes <= maxOperations)
{
// 修改上界
maxValue = mid;
}
else
{
// 否则修改下界
minValue = mid;
}
}
// 最终返回二分查找上界
return maxValue;
}
};