你有一大块巧克力,它由一些甜度不完全相同的小块组成。我们用数组 sweetness 来表示每一小块的甜度。
你打算和 K 名朋友一起分享这块巧克力,所以你需要将切割 K 次才能得到 K+1 块,每一块都由一些 连续 的小块组成。
为了表现出你的慷慨,你将会吃掉 总甜度最小 的一块,并将其余几块分给你的朋友们。
请找出一个最佳的切割策略,使得你所分得的巧克力 总甜度最大,并返回这个 最大总甜度。
示例 1:
输入:sweetness = [1,2,3,4,5,6,7,8,9], K = 5
输出:6
解释:你可以把巧克力分成 [1,2,3], [4,5], [6], [7], [8], [9]。
示例 2:
输入:sweetness = [5,6,7,8,9,1,2,3,4], K = 8
输出:1
解释:只有一种办法可以把巧克力分成 9 块。
示例 3:
输入:sweetness = [1,2,2,1,2,2,1,2,2], K = 2
输出:5
解释:你可以把巧克力分成 [1,2,2], [1,2,2], [1,2,2]。
提示:
0 <= K < sweetness.length <= 10^4
1 <= sweetness[i] <= 10^5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/divide-chocolate
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
新鲜的今天🐶家电面题。
这题就是我在LeetCode-Python-1011. 在 D 天内送达包裹的能力最下面附上的面经题的第一题……
首先读完题马上就可以猜到答案落在的区间【min(sweetness), sum(sweetness)//(k + 1)】,
然后用二分法不断缩小区间范围即可。
类似题型还有:
410, 875, 1011, 1201,都是同一种套路,先观察题意,猜到答案区间,然后二分求解。
class Solution(object):
def maximizeSweetness(self, sweetness, K):
"""
:type sweetness: List[int]
:type K: int
:rtype: int
"""
left = min(sweetness) # 结果的最小值
right = sum(sweetness)//(K + 1) # 结果的最大值
while left <= right:
mid = (left + right) // 2
cnt = 0 # 用来记录当我分到的巧克力甜度为mid的时候,切的总块数
tmp = 0 # 当前切的这块巧克力的总甜度
for sweet in sweetness:
if (tmp + sweet) > mid:
cnt += 1
tmp = 0
else:
tmp += sweet
if cnt < K + 1: # 需要切更多块
right = mid - 1
else:
left = mid + 1
return left