1760. 袋子里最少数目的球

目录

题目解析:最小化拆分袋子中球的最大数量

题目描述

题目示例

示例 1

示例 2

示例 3

解题分析

为什么使用二分搜索?

如何判断可行?

解题方法(代码)

复杂度分析

示例说明与验证

总结


题目解析:最小化拆分袋子中球的最大数量

题目描述

给你一个整数数组 nums,其中 nums[i] 表示第 i 个袋子里球的数目。同时给你一个整数 maxOperations

你可以进行如下操作最多 maxOperations 次:

  • 选择任意一个袋子,将袋子里的球分到 2 个新的袋子中,每个新袋子里都有 正整数 个球。

例如,一个袋子里有 5 个球,可以拆分成两个新袋子,分别有 1 个和 4 个球,或者分别有 2 个和 3 个球。

你的目标是最小化拆分操作后,所有袋子中球数目的最大值(即开销)

请你返回这个最小的最大球数。


题目示例

示例 1

输入:nums = [9], maxOperations = 2
输出:3

解释:
- 第一次拆分:9 -> 6 和 3
- 第二次拆分:6 -> 3 和 3
拆分后袋子分别为 [3,3,3],最大袋子球数为 3,返回 3。

示例 2

输入:nums = [2,4,8,2], maxOperations = 4
输出:2

解释:
- 将8拆成4和4:[2,4,4,4,2]
- 拆4成2和2:[2,4,4,4,2] -> [2,2,2,4,4,2]
- 再拆两个4为2和2,最多拆4次
最终所有袋子最大球数为2。

示例 3

输入:nums = [7,17], maxOperations = 2
输出:7

解题分析

这道题的核心在于,给定一个限制的最大袋子容量 x,判断是否能通过最多 maxOperations 次拆分,将所有袋子的球数都控制在 x 以下。然后利用二分搜索寻找最小的 x

为什么使用二分搜索?

  • 开销范围:最大开销的最小值至少是 1(每袋至少有1个球),最大值是 max(nums)(不拆分的最大袋子数)。
  • 单调性:如果最大容量限制为 x 可以完成拆分,那么任何大于 x 的容量也肯定可以完成拆分;反之,不可行。
  • 因此,答案在 [1, max(nums)] 这个区间内具有单调性质,可以用二分搜索找最小可行解。

如何判断可行?

对每个袋子:

  • 若袋子里球数 num <= x,不需要拆分,操作数为0。
  • num > x,需要拆分成若干个不超过 x 的袋子。

拆分次数计算方法:

  • 袋子拆成的袋子数 = ceil(num / x),拆分次数 = 拆成的袋子数 - 1
  • 数学表达式:拆分次数 = (num - 1) // x

累加所有袋子的拆分次数,若总拆分次数 ≤ maxOperations,说明 x 是可行的。


解题方法(代码)

from typing import List

class Solution:
    def minimumSize(self, nums: List[int], maxOperations: int) -> int:
        def can_split(max_size):
            operations = 0
            for num in nums:
                # 拆分次数 = (num - 1) // max_size
                operations += (num - 1) // max_size
                if operations > maxOperations:
                    return False
            return True

        left, right = 1, max(nums)
        while left < right:
            mid = (left + right) // 2
            if can_split(mid):
                right = mid
            else:
                left = mid + 1
        return left

复杂度分析

  • 时间复杂度
    • 二分搜索的范围为 [1, max(nums)],假设最大球数为 m,则二分搜索最多进行 O(log m) 次。
    • 每次判断需要遍历所有袋子,时间为 O(n)
    • 总时间复杂度为 O(n log m)
  • 空间复杂度
    • 只使用了常数额外空间,空间复杂度为 O(1)

示例说明与验证

以示例 1 为例:

  • nums = [9], maxOperations = 2
  • 搜索范围:1 到 9

尝试中间值:

  • mid=5,拆分9:需要 (9-1)//5=1 次拆分,1 <= 2 可行,右边界收缩到5
  • mid=3,拆分9: (9-1)//3=2 次拆分,2 <= 2 可行,右边界收缩到3
  • mid=2,拆分9: (9-1)//2=4 次拆分,4 > 2 不可行,左边界收缩到3

最终左边界3,即最小最大开销为3。


总结

这道题通过二分搜索 + 贪心拆分实现高效求解,关键是:

  • 明确目标函数是“最大袋子球数”的最小值。
  • 利用二分搜索缩小答案范围。
  • 设计一个判断函数,根据给定最大容量判断是否能在操作限制内拆分完成。

该题模式在很多分割、拆分和最大容量限制类问题中常见,掌握该方法有助于解决类似题目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值