问题:
给定一个花圃,每个元素表示该位置的花,开花所需要的天数。
要求用连续k个位置上的花组成一个花束,共组成m个花束,所需要的最短天数。
Example 1: Input: bloomDay = [1,10,3,10,2], m = 3, k = 1 Output: 3 Explanation: Let's see what happened in the first three days. x means flower bloomed and _ means flower didn't bloom in the garden. We need 3 bouquets each should contain 1 flower. After day 1: [x, _, _, _, _] // we can only make one bouquet. After day 2: [x, _, _, _, x] // we can only make two bouquets. After day 3: [x, _, x, _, x] // we can make 3 bouquets. The answer is 3. Example 2: Input: bloomDay = [1,10,3,10,2], m = 3, k = 2 Output: -1 Explanation: We need 3 bouquets each has 2 flowers, that means we need 6 flowers. We only have 5 flowers so it is impossible to get the needed bouquets and we return -1. Example 3: Input: bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3 Output: 12 Explanation: We need 2 bouquets each should have 3 flowers. Here's the garden after the 7 and 12 days: After day 7: [x, x, x, x, _, x, x] We can make one bouquet of the first three flowers that bloomed. We cannot make another bouquet from the last three flowers that bloomed because they are not adjacent. After day 12: [x, x, x, x, x, x, x] It is obvious that we can make two bouquets in different ways. Example 4: Input: bloomDay = [1000000000,1000000000], m = 1, k = 1 Output: 1000000000 Explanation: You need to wait 1000000000 days to have a flower ready for a bouquet. Example 5: Input: bloomDay = [1,10,2,9,3,8,4,7,5,6], m = 4, k = 2 Output: 9 Constraints: bloomDay.length == n 1 <= n <= 10^5 1 <= bloomDay[i] <= 10^9 1 <= m <= 10^6 1 <= k <= n
解法:二分查找(Binary Search)
⚠️ 注意:特别的,若所需要的花束位置总数m*k > 给出的花圃位置总数,返回-1。
本问题中,我们找到第一个(最小)使得开出花后,能束成花束个数>=m个花束,的天数。
天数的范围:
- 最小:l:1天
- 最大:r:max(bloomDay)+1 (左闭右开区间)
我们需要实现判断函数g(x):mid天能组成花束的个数。
(参数:连续k个位置的花能构成1束花束)
int getBouquetsCount(vector<int>& bloomDay, int k, int D)
代码参考:
1 class Solution { 2 public: 3 int getBouquetsCount(vector<int>& bloomDay, int k, int D) { 4 //给定D天内,最多能获得多少束花。 5 int cout = 0; 6 int cur = 0; 7 for(int bD:bloomDay) { 8 if(bD>D) { 9 cur=0; 10 } else { 11 cur++; 12 if(cur==k) { 13 cout++; 14 cur=0; 15 } 16 } 17 } 18 return cout; 19 } 20 int minDays(vector<int>& bloomDay, int m, int k) { 21 int res = 0; 22 int l = INT_MAX, r = 1; 23 if(m*k > bloomDay.size()) return -1; 24 for(int bD:bloomDay) { 25 l = min(l, bD); 26 r = max(r, bD); 27 } 28 r = r+1; 29 30 while(l<r) { 31 int mid = l+(r-l)/2; 32 if(getBouquetsCount(bloomDay, k, mid) >= m) { 33 r = mid; 34 } else { 35 l = mid+1; 36 } 37 } 38 return l; 39 } 40 };