Leetcode 1482
这是5.9号的题目 1482. 制作 m 束花所需的最少天数
二分的应用场景不一定有序,只要具备排他性、两段性,就可以二分
寻找最优临界值的题目,往往可以借助二分搜索
/**
* @param bloomDay 什么时候开花
* @param m m束
* @param k k朵花做成一束
* @return
*/
public static int minDays(int[] bloomDay, int m, int k) {
int n = bloomDay.length;
if (n < m * k)//不够花束
return -1;
int low = Integer.MAX_VALUE, high = 0;
for (int i = 0; i < n; i++) {
low = Math.min(low, bloomDay[i]);//找到最小值作为low
high = Math.max(high, bloomDay[i]);//找到最大值作为high
}
while (low < high) {//不断靠近目标值,当low = high时,此时即为最少天数
int days = (high - low) / 2 + low;
if (canMake(bloomDay, days, m, k)) {
high = days;
} else {
low = days + 1;
}
}
return low;
}
//辅助函数,找到临界点
public static boolean canMake(int[] bloomDay, int days, int m, int k) {
//在确保可以制作出指定数量的花束的情况下,所需的最少天数一定会大于min,小于max
//days很小的时候,总是返回false,不够做够花束,而days很大的时候,则总是返回true
int bouquets = 0;
int flowers = 0;
int length = bloomDay.length;
for (int i = 0; i < length && bouquets < m; i++) {
if (bloomDay[i] <= days) {
flowers++;
if (flowers == k) {
bouquets++;
flowers = 0;
}
} else {
flowers = 0;
}
}
return bouquets >= m;
}