制作m束花所需的最少天数
题目要求
解题思路
二分法
读完题目发现:
- 制作花朵最少的时间必然是bloomDay数组中开花所用的天数最少的那朵花
min(bloomDay)
- 制作花朵最多的时间必然是
max(bloomDay)
- 寻找制作花束的最少天数必然落在上面所说的区间里[min(bloomDay),max(bloomDay)]
细节处理
除了以上的一些问题,还有一些细节来填充。 - 数组中的花朵不够用来制作花束的,直接返回-1
- 必须是连续的花朵,这个可以通过变量
flower
来计数是否连续,一旦不连续就重置为0; - 没满足一次连续的k朵花,就可以制作一束花,
flower
计数重新为0开始计数
代码
class Solution:
def minDays(self, bloomDay: List[int], m: int, k: int) -> int:
n = len(bloomDay)
N = m*k
if n<N: return -1
left = min(bloomDay)
right = max(bloomDay)
while left < right:
# 假设尝试 mid 作为最小的天数, 看看能不能制作要求的花束
mid = (left + right) // 2
# 如果可以制作花束, 那么可以尝试天数再减小一点, 因此right往左走, 缩小搜索范围
if self.canMake(bloomDay, mid, m, k):
right = mid
# 如果无法制作花束, 那么可以尝试天数再增大一点, 因此left往右边走, 区间的左边值加大
else:
left = mid + 1
return left
def canMake(self, bloomDay: List[int], days: int, m: int, k:int) -> bool:
# 数连续的花朵数量
flower = 0
# 记录花束
bouquet = 0
for i in range(len(bloomDay)):
if bloomDay[i] <= days:
flower += 1
if flower == k:
bouquet += 1
# 置0, 重新开始计算
flower = 0
else:
# 表示花朵不连续了, 置 0
flower = 0
if bouquet >= m:
break
return bouquet >= m
复杂度分析
时间复杂度:
O
(
n
l
o
g
m
)
O(n log m)
O(nlogm)
空间复杂度:
O
(
1
)
O(1)
O(1)