In a row of flowers, each flower blooms on a specific day. Given an integer array arr[], where arr[i] denotes the day on which the flower at position i blooms.
To make a bouquet, you need to collect k adjacent flowers that have already bloomed. Each flower can be used in at most one bouquet.
Find the minimum number of days required to make m bouquets. If it is impossible to do so, return -1.
Examples:
Input: arr[] = [3, 4, 2, 7, 13, 8, 5], m = 3, k = 2
Output: 8
Explanation: We need to make 3 bouquets, each consisting of 2 adjacent flowers.
-> By day 8, all flowers have bloomed except the flower at position 5 (1-indexed).
-> Form the 1st bouquet using the first 2 flowers.
-> Form the 2nd bouquet using the next 2 flowers.
-> Form the 3rd bouquet using the last 2 flowers.Input: arr[] = [5, 5, 5, 5, 10, 5, 5], m = 2, k = 3
Output: 10
Explanation: We need to make 2 bouquets, each consisting of 3 adjacent flowers.
-> By day 5, all flowers have bloomed except the flower at position 5 (1-indexed).
-> We can form the 1st bouquet using the first 3 bloomed flowers.
-> It is not possible to form the 2nd bouquet now.
-> By day 10, all the flowers have bloomed.
-> We can then form 2 bouquets, each consisting of 3 adjacent flowers.Input: arr[] = [1, 10, 3, 10, 2], m = 3, k = 2
Output: -1
Explanation: We need to make 3 bouquets, each consisting of 2 flowers.
-> This requires a total of 6 flowers.
-> There are only 5 flowers available.
-> Therefore, it is impossible to make the required bouquets.
Table of Content
[Naive Approach] Using Linear Search - O(n × max(arr)) Time and O(1) Space
The idea is to iterate over all possible days d starting from 0 to largest bloom day. To find whether it is possible to make m bouquets in d days, we traverse the array arr[] and check if there is at least m contiguous subarrays of size k such that each subarray has element <= d.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
bool check(vector<int> &arr, int k, int m, int days) {
int bouquets = 0;
int cnt = 0;
// iterate through the bloom days of the flowers
for (int i = 0; i < arr.size(); i++) {
if (arr[i] <= days) {
cnt += 1;
}
else {
// if the current bloom day count is greater
// than days, update bouquets and reset count
bouquets += cnt / k;
cnt = 0;
}
}
bouquets += cnt / k;
// check if current bouquets are greater than or
// equal to the desired number of bouquets (m)
return bouquets >= m;
}
int minDaysBloom(vector<int> &arr, int k, int m) {
int maxDays = *max_element(arr.begin(), arr.end());
for (int d = 0; d <= maxDays; d++) {
if (check(arr, k, m, d))
return d;
}
return -1;
}
int main() {
vector<int> arr = {5, 5, 5, 5, 10, 5, 5};
int k = 3, m = 2;
cout << minDaysBloom(arr, k, m);
return 0;
}
import java.util.Arrays;
class GFG {
static boolean check(int[] arr, int k,
int m, int days){
int bouquets = 0;
int cnt = 0;
// iterate through the bloom days of the flowers
for (int i = 0; i < arr.length; i++) {
if (arr[i] <= days) {
cnt += 1;
}
else {
// if the current bloom day count is greater
// than days, update bouquets and reset count
bouquets += cnt / k;
cnt = 0;
}
}
bouquets += cnt / k;
// check if current bouquets are greater than or
// equal to the desired number of bouquets (m)
return bouquets >= m;
}
static int minDaysBloom(int[] arr, int k, int m) {
int maxDays = Arrays.stream(arr).max().getAsInt();
for (int d = 0; d <= maxDays; d++) {
if (check(arr, k, m, d))
return d;
}
return -1;
}
public static void main(String[] args) {
int[] arr = {5, 5, 5, 5, 10, 5, 5};
int k = 3, m = 2;
System.out.println(minDaysBloom(arr, k, m));
}
}
def check(arr, k, m, days):
bouquets = 0
cnt = 0
# iterate through the bloom days of the flowers
for i in range(len(arr)):
if arr[i] <= days:
cnt += 1
else:
# if the current bloom day count is greater
# than days, update bouquets and reset count
bouquets += cnt // k
cnt = 0
bouquets += cnt // k
# check if current bouquets are greater than or
# equal to the desired number of bouquets (m)
return bouquets >= m
def minDaysBloom(arr, k, m):
maxDays = max(arr)
for d in range(maxDays + 1):
if check(arr, k, m, d):
return d
return -1
if __name__ == "__main__":
arr = [5, 5, 5, 5, 10, 5, 5]
k = 3
m = 2
print(minDaysBloom(arr, k, m))
using System;
using System.Linq;
class GFG {
static bool check(int[] arr, int k, int m, int days) {
int bouquets = 0;
int cnt = 0;
// Iterate through the bloom days of the flowers
for (int i = 0; i < arr.Length; i++) {
if (arr[i] <= days) {
cnt += 1;
}
else {
// If the current bloom day count is greater
// than days, update bouquets and reset count
bouquets += cnt / k;
cnt = 0;
}
}
bouquets += cnt / k;
// Check if current bouquets are greater than or
// equal to the desired number of bouquets (m)
return bouquets >= m;
}
static int minDaysBloom(int[] arr, int k, int m) {
int maxDays = arr.Max();
for (int d = 0; d <= maxDays; d++) {
if (check(arr, k, m, d))
return d;
}
return -1;
}
static void Main() {
int[] arr = { 5, 5, 5, 5, 10, 5, 5 };
int k = 3, m = 2;
Console.WriteLine(minDaysBloom(arr, k, m));
}
}
function check(arr, k, m, days) {
let bouquets = 0;
let cnt = 0;
// iterate through the bloom days of the flowers
for (let i = 0; i < arr.length; i++) {
if (arr[i] <= days) {
cnt += 1;
} else {
// if the current bloom day count is greater
// than days, update bouquets and reset count
bouquets += Math.floor(cnt / k);
cnt = 0;
}
}
bouquets += Math.floor(cnt / k);
// check if current bouquets are greater than or
// equal to the desired number of bouquets (m)
return bouquets >= m;
}
function minDaysBloom(arr, k, m) {
const maxDays = Math.max(...arr);
for (let d = 0; d <= maxDays; d++) {
if (check(arr, k, m, d))
return d;
}
return -1;
}
// Driver Code
const arr = [5, 5, 5, 5, 10, 5, 5];
const k = 3;
const m = 2;
console.log(minDaysBloom(arr, k, m));
Output
10
[Expected Approach] Using Binary Search
The idea is to use Binary search on answer. Our search space would be 0 to largest bloom day of flower, which represent the range in which minimum number of required days will lie. Now, calculate mid and check if mid days is possible to make m bouquet, such that k bloomed adjacent flowers can be selected to make a bouquet.
=> If possible then update the result with mid value and move towards lesser values in search space by updating high to mid - 1.
=> Otherwise, move towards larger values in search space by updating low to mid + 1.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool check(vector<int>& arr, int k, int m,
int days) {
int bouquets = 0;
int cnt = 0;
// iterate through the bloom
// days of the flowers
for (int i = 0; i < arr.size(); i++) {
if (arr[i] <= days) {
cnt += 1;
}
else {
// if the current bloom day count
// is greater than days, update
// the bouquets and reset count
bouquets += cnt / k;
cnt = 0;
}
}
bouquets += cnt / k;
// check if current bouquets are greater
// than or equal to the desired
// number of bouquets (m)
return bouquets >= m;
}
int minDaysBloom(vector<int>& arr, int k, int m) {
int lo = 0;
int hi = *max_element(arr.begin(), arr.end());
int res = -1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (check(arr, k, m, mid)) {
// if the current mid is
// valid, update the result
// and adjust the search range
res = mid;
hi = mid - 1;
}
else {
// if the current mid is
// not valid, adjust the
// search range
lo = mid + 1;
}
}
return res;
}
int main() {
vector<int> arr = {5, 5, 5, 5, 10, 5, 5};
int k = 3, m = 2;
cout << minDaysBloom(arr, k, m);
return 0;
}
import java.util.Arrays;
class GFG {
static boolean check(int[] arr, int k,
int m, int days) {
int bouquets = 0;
int cnt = 0;
// iterate through the bloom
// days of the flowers
for (int i = 0; i < arr.length; i++) {
if (arr[i] <= days) {
cnt += 1;
} else {
// if the current bloom day count
// is greater than days, update
// the bouquets and reset count
bouquets += cnt / k;
cnt = 0;
}
}
bouquets += cnt / k;
// check if current bouquets are greater
// than or equal to the desired
// number of bouquets (m)
return bouquets >= m;
}
static int minDaysBloom(int[] arr, int k, int m) {
int lo = 0;
int hi = Arrays.stream(arr).max().getAsInt();
int res = -1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (check(arr, k, m, mid)) {
// if the current mid is valid update
// the result and adjust the search range
res = mid;
hi = mid - 1;
}
else {
// if the current mid is not valid
// adjust the search range
lo = mid + 1;
}
}
return res;
}
public static void main(String[] args) {
int[] arr = {5, 5, 5, 5, 10, 5, 5};
int k = 3, m = 2;
System.out.println(minDaysBloom(arr, k, m));
}
}
def check(arr, k, m, days):
bouquets = 0
cnt = 0
# iterate through the bloom
# days of the flowers
for flower in arr:
if flower <= days:
cnt += 1
else:
# if the current bloom day count
# is greater than days, update
# the bouquets and reset count
bouquets += cnt // k
cnt = 0
bouquets += cnt // k
# check if current bouquets are greater
# than or equal to the desired
# number of bouquets (m)
return bouquets >= m
def minDaysBloom(arr, k, m):
lo = 0
hi = max(arr)
res = -1
while lo <= hi:
mid = (lo + hi) // 2
if check(arr, k, m, mid):
# if the current mid is valid update the result
# and adjust the search range
res = mid
hi = mid - 1
else:
# if the current mid is not valid
# adjust the search range
lo = mid + 1
return res
if __name__ == "__main__":
arr = [5, 5, 5, 5, 10, 5, 5]
k = 3
m = 2
print(minDaysBloom(arr, k, m))
using System;
using System.Linq;
class GFG {
static bool check(int[] arr, int k,
int m, int days) {
int bouquets = 0;
int cnt = 0;
// Iterate through the bloom
// days of the flowers
for (int i = 0; i < arr.Length; i++) {
if (arr[i] <= days) {
cnt += 1;
} else {
// If the current bloom day count
// is greater than days, update
// the bouquets and reset count
bouquets += cnt / k;
cnt = 0;
}
}
bouquets += cnt / k;
// Check if current bouquets are greater
// than or equal to the desired
// number of bouquets (m)
return bouquets >= m;
}
static int minDaysBloom(int[] arr, int k, int m) {
int lo = 0;
int hi = arr.Max();
int res = -1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (check(arr, k, m, mid)) {
// if the current mid is valid, update the
// result and adjust the search range
res = mid;
hi = mid - 1;
} else {
// if the current mid is not valid
// adjust the search range
lo = mid + 1;
}
}
return res;
}
static void Main() {
int[] arr = {5, 5, 5, 5, 10, 5, 5};
int k = 3;
int m = 2;
Console.WriteLine(minDaysBloom(arr, k, m));
}
}
function check(arr, k, m, days) {
let bouquets = 0;
let cnt = 0;
// iterate through the bloom
// days of the flowers
for (let i = 0; i < arr.length; i++) {
if (arr[i] <= days) {
cnt += 1;
}
else {
// if the current bloom day count
// is greater than days, update
// the bouquets and reset count
bouquets += Math.floor(cnt / k);
cnt = 0;
}
}
bouquets += Math.floor(cnt / k);
// check if current bouquets are greater
// than or equal to the desired
// number of bouquets (m)
return bouquets >= m;
}
function minDaysBloom(arr, k, m) {
let lo = 0;
let hi = Math.max(...arr);
let res = -1;
while (lo <= hi) {
let mid = Math.floor((lo + hi) / 2);
if (check(arr, k, m, mid)) {
// if the current mid is valid update the
// result and adjust the search range
res = mid;
hi = mid - 1;
} else {
// if the current mid is not valid
// adjust the search range
lo = mid + 1;
}
}
return res;
}
// Driver Code
let arr = [5, 5, 5, 5, 10, 5, 5];
let k = 3;
let m = 2;
console.log(minDaysBloom(arr, k, m));
Output
10
Time complexity: O(n × log(maxDays)), where n is the number of elements in the array, and maxDays is the maximum possible number of days for a flower to bloom.
Auxiliary Space: O(1)