今天是母亲节,今日力扣的题是关于制作花的!让我们做花献给我们伟大的母亲。
言归正传:看题目,给你一个整数数组 bloomDay,以及两个整数 m 和 k 。
现需要制作 m 束花。制作花束时,需要使用花园中 相邻的 k 朵花 。
花园中有 n 朵花,第 i 朵花会在 bloomDay[i] 时盛开,恰好 可以用于 一束 花中。
请你返回从花园中摘 m 束花需要等待的最少的天数。如果不能摘到 m 束花则返回 -1 。
从题目可以知道,在一个数组的花中,数组各个元素的值就是该花需要多少天才能摘,题目要求制作m束花,每一束花又需要数组中相邻的k朵花,所以如果不是相邻连续的花是不能做成一束花的。另外,很明显数组的大小必须大于或等于m*k,否则压根不足以制作m束花。看示例:
示例1:
输入:bloomDay = [1,10,3,10,2], m = 3, k = 2
输出:-1
解释:要制作 3 束花,每束需要 2 朵花,也就是一共需要 6 朵花。而花园中只有 5 朵花,无法满足制作要求,返回 -1 。
示例2:
输入:bloomDay = [1000000000,1000000000], m = 1, k = 1
输出:1000000000
解释:需要等 1000000000 天才能采到花来制作花束
示例3 :
输入:bloomDay = [1,10,2,9,3,8,4,7,5,6], m = 4, k = 2
输出:9
示例4:
输入:bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3
输出:12
解释:要制作 2 束花,每束需要 3 朵。
花园在 7 天后和 12 天后的情况如下:
7 天后:[x, x, x, x, _, x, x]
可以用前 3 朵盛开的花制作第一束花。但不能使用后 3 朵盛开的花,因为它们不相邻。
12 天后:[x, x, x, x, x, x, x]
显然,我们可以用不同的方式制作两束花。
如果你看示例,看题目没有思路,看看这两张照片可能你思路就来了!(图片非原创)
看完这两张图片很快就知道该如何下手了!二分法!如果还不清楚可以看我的注释
func minDays(bloomDay []int, m int, k int) int {
if m*k > len(bloomDay){ \\如果m*k大于数组长度,就根本做不了m束花,直接返回-1
return -1
}
left,right := 1,1
for _,v := range bloomDay{ \\找到数组中最大的天数
if right < v{
right = v
}
}
\\开始二分查找最小的天数left
for left < right{
mid := (left+right)/2 \\用left与right的中间值尝试能不能找到结果
cnt := 0 \\用于记录连续的k朵
fnum := 0 \\用于记录能不能做成m束花
for _,v := range bloomDay{ \\开始遍历数组,以mid作为限制天数看看能不能做成m朵花
if v > mid{ \\如果有大于mid的,说明连续的cnt中断
cnt = 0 \\所以要重新置0,并跳过本次循环
continue
}
cnt++ \\否则说明是连续小于mid的花
if cnt == k{ \\当cnt达到k朵可以做成1束花的时候,fnum+1,cnt置0
fnum++
cnt = 0
if fnum == m{ \\如果fnum已经可以做m束花,直接退出当前for
break
}
}
}
if fnum >= m { \\既然当前的mid可以做成m束花,那么尝试right=mid的情况
right = mid
}else{ \\既然当前的mid无法做成m束花,那么尝试left=mid+1的情况,也就意味着最小天数比mid大
left = mid + 1
}
}
\\直到最后已经无法在二分的时候那个left就是最小天数
return left
}
为了方便看注释,我把反斜杠反过来了,这样中文看着就不会那么吃力了!是不是很清晰很简单!
要坚持每天学习喔,加油。