Given a garden with n flowers planted in a row, represented by an array arr[], where arr[i] denotes the height of the ith flower. You have exactly k days to water the flowers.
Each day, you can choose any group of w consecutive flowers and water them. Watering increases the height of each flower in the selected group by 1. This operation can be performed once per day. find the maximum possible minimum height of any flower in the garden after k days of watering.
Examples:
Input: arr[] = [2, 3, 4, 5, 1], k = 2, w = 2
Output: 2
Explanation: The minimum height after watering is 2.
Day 1: Water the last two flowers → arr becomes [2, 3, 4, 6, 2]
Day 2: Again water the last two flowers → arr becomes [2, 3, 4, 7, 3]Input: arr[] = [5, 8], k = 5, w = 1
Output: 9
Explanation: The minimum height after watering is 9.
Day 1 - Day 4: Water the first flower → arr becomes [9, 8]
Day 5: Water the second flower → arr becomes [9, 9]Input: arr[] = [2, 2, 2, 2, 1, 1], k = 2, w = 3,
Output: 2
Table of Content
[Naive Approach] Linearly Check for all Values – O(n*m) Time and O(n) Space
The idea is to keep increasing the minimum height level by 1 step at a time as long as it is possible within the given k days. The thought process is to simulate the watering process carefully, checking at every stage whether we have enough operations to maintain all flowers at or above the new height. An important observation is that watering w consecutive flowers at once lets us push groups upward together, helping balance the heights. We stop once we cannot raise the minimum height further without exceeding the allowed number of days.
#include <iostream>
#include <vector>
using namespace std;
int maxMinHeight(vector<int> &arr, int k, int w) {
int n = arr.size();
int maxHeight = 0;
// Try increasing the minimum height
// as long as possible
while (true) {
int days = k;
vector<int> water(n, 0);
bool possible = true;
for (int i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
int currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight + 1) {
int add = maxHeight + 1 - currHeight;
water[i] += add;
days -= add;
// If days become negative, not possible
if (days < 0) {
possible = false;
break;
}
}
}
// Break if we can't raise height further
if (!possible) {
break;
}
// Otherwise increase maxHeight
maxHeight++;
}
return maxHeight;
}
// Driver code
int main() {
vector<int> arr = {2, 3, 4, 5, 1};
int k = 2;
int w = 2;
cout << maxMinHeight(arr, k, w);
return 0;
}
class GfG {
static int maxMinHeight(int[] arr, int k, int w) {
int n = arr.length;
int maxHeight = 0;
// Try increasing the minimum height
// as long as possible
while (true) {
int days = k;
int[] water = new int[n];
boolean possible = true;
for (int i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
int currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight + 1) {
int add = maxHeight + 1 - currHeight;
water[i] += add;
days -= add;
// If days become negative, not possible
if (days < 0) {
possible = false;
break;
}
}
}
// Break if we can't raise height further
if (!possible) {
break;
}
// Otherwise increase maxHeight
maxHeight++;
}
return maxHeight;
}
// Driver code
public static void main(String[] args) {
int[] arr = {2, 3, 4, 5, 1};
int k = 2;
int w = 2;
System.out.println(maxMinHeight(arr, k, w));
}
}
def maxMinHeight(arr, k, w):
n = len(arr)
maxHeight = 0
# Try increasing the minimum height
# as long as possible
while True:
days = k
water = [0] * n
possible = True
for i in range(n):
# Add previous watering effect
if i > 0:
water[i] = water[i - 1]
currHeight = arr[i] + water[i]
# Remove watering effect beyond window w
if i >= w:
currHeight -= water[i - w]
# If current height is less than required
if currHeight < maxHeight + 1:
add = maxHeight + 1 - currHeight
water[i] += add
days -= add
# If days become negative, not possible
if days < 0:
possible = False
break
# Break if we can't raise height further
if not possible:
break
# Otherwise increase maxHeight
maxHeight += 1
return maxHeight
# Driver code
if __name__ == "__main__":
arr = [2, 3, 4, 5, 1]
k = 2
w = 2
print(maxMinHeight(arr, k, w))
// C# program to maximize the minimum height
// using Naive approach
using System;
class GfG {
// Main function to maximize minimum height
static int maxMinHeight(int[] arr, int k, int w) {
int n = arr.Length;
int maxHeight = 0;
// Try increasing the minimum height
// as long as possible
while (true) {
int days = k;
int[] water = new int[n];
bool possible = true;
for (int i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
int currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight + 1) {
int add = maxHeight + 1 - currHeight;
water[i] += add;
days -= add;
// If days become negative, not possible
if (days < 0) {
possible = false;
break;
}
}
}
// Break if we can't raise height further
if (!possible) {
break;
}
// Otherwise increase maxHeight
maxHeight++;
}
return maxHeight;
}
// Driver code
public static void Main() {
int[] arr = {2, 3, 4, 5, 1};
int k = 2;
int w = 2;
Console.WriteLine(maxMinHeight(arr, k, w));
}
}
function maxMinHeight(arr, k, w) {
let n = arr.length;
let maxHeight = 0;
// Try increasing the minimum height
// as long as possible
while (true) {
let days = k;
let water = new Array(n).fill(0);
let possible = true;
for (let i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
let currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight + 1) {
let add = maxHeight + 1 - currHeight;
water[i] += add;
days -= add;
// If days become negative, not possible
if (days < 0) {
possible = false;
break;
}
}
}
// Break if we can't raise height further
if (!possible) {
break;
}
// Otherwise increase maxHeight
maxHeight++;
}
return maxHeight;
}
// Driver code
let arr = [2, 3, 4, 5, 1];
let k = 2;
let w = 2;
console.log(maxMinHeight(arr, k, w));
Output
2
Time Complexity: O(n*m), where n is the number of elements and m is the maximum minimum height achieved. For each height level, we scan the entire array once.
Space Complexity: O(n), due to the extra water array used to track the cumulative watering effects across positions.
[Expected Approach] Using Binary Search – O(n*log(m)) Time and O(n) Space
The idea is to use binary search on the minimum achievable height instead of checking every height. The search range goes from the initial minimum height to the minimum height plus all available watering days (
k), assuming we use all efforts on the smallest flowers. For each midpoint, we simulate the watering process to see if it's possible to raise every flower to at least that height usingkdays and a watering window of sizew. Since the number of required days increases with the target height, the problem has a monotonic property, making binary search an efficient choice.
#include <iostream>
#include <vector>
using namespace std;
// Function to check if it is possible to make
// every flower at least minHeight with given days
bool isPossible(vector<int> &arr, int k,
int w, int maxHeight) {
int n = arr.size();
vector<int> water(n, 0);
for (int i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
int currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight) {
int add = maxHeight - currHeight;
water[i] += add;
k -= add;
// If days become negative, not possible
if (k < 0) {
return false;
}
}
}
return true;
}
int maxMinHeight(vector<int> &arr, int k, int w) {
int n = arr.size();
// Find minimum height manually
int low = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] < low) {
low = arr[i];
}
}
int high = low + k;
int ans = low;
// Binary Search on the answer
while (low <= high) {
int mid = low + (high - low) / 2;
if (isPossible(arr, k, w, mid)) {
ans = max(ans, mid);
low = mid + 1;
} else {
high = mid - 1;
}
}
return ans;
}
// Driver code
int main() {
vector<int> arr = {2, 3, 4, 5, 1};
int k = 2;
int w = 2;
cout << maxMinHeight(arr, k, w);
return 0;
}
class GfG {
// Function to check if it is possible to make
// every flower at least minHeight with given days
static boolean isPossible(int[] arr, int k,
int w, int maxHeight) {
int n = arr.length;
int[] water = new int[n];
for (int i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
int currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight) {
int add = maxHeight - currHeight;
water[i] += add;
k -= add;
// If days become negative, not possible
if (k < 0) {
return false;
}
}
}
return true;
}
static int maxMinHeight(int[] arr, int k, int w) {
int n = arr.length;
// Find minimum height manually
int low = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] < low) {
low = arr[i];
}
}
int high = low + k;
int ans = low;
// Binary Search on the answer
while (low <= high) {
int mid = low + (high - low) / 2;
if (isPossible(arr, k, w, mid)) {
ans = Math.max(ans, mid);
low = mid + 1;
} else {
high = mid - 1;
}
}
return ans;
}
public static void main(String[] args) {
int[] arr = {2, 3, 4, 5, 1};
int k = 2;
int w = 2;
System.out.println(maxMinHeight(arr, k, w));
}
}
def isPossible(arr, k, w, maxHeight):
n = len(arr)
water = [0] * n
for i in range(n):
# Add previous watering effect
if i > 0:
water[i] = water[i - 1]
currHeight = arr[i] + water[i]
# Remove watering effect beyond window w
if i >= w:
currHeight -= water[i - w]
# If current height is less than required
if currHeight < maxHeight:
add = maxHeight - currHeight
water[i] += add
k -= add
# If days become negative, not possible
if k < 0:
return False
return True
def maxMinHeight(arr, k, w):
n = len(arr)
# Find minimum height manually
low = arr[0]
for i in range(1, n):
if arr[i] < low:
low = arr[i]
high = low + k
ans = low
# Binary Search on the answer
while low <= high:
mid = low + (high - low) // 2
if isPossible(arr, k, w, mid):
ans = max(ans, mid)
low = mid + 1
else:
high = mid - 1
return ans
if __name__ == "__main__":
arr = [2, 3, 4, 5, 1]
k = 2
w = 2
print(maxMinHeight(arr, k, w))
using System;
class GfG {
// Function to check if it is possible to make
// every flower at least minHeight with given days
static bool isPossible(int[] arr, int k,
int w, int maxHeight) {
int n = arr.Length;
int[] water = new int[n];
for (int i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
int currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight) {
int add = maxHeight - currHeight;
water[i] += add;
k -= add;
// If days become negative, not possible
if (k < 0) {
return false;
}
}
}
return true;
}
static int maxMinHeight(int[] arr, int k, int w) {
int n = arr.Length;
// Find minimum height manually
int low = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] < low) {
low = arr[i];
}
}
int high = low + k;
int ans = low;
// Binary Search on the answer
while (low <= high) {
int mid = low + (high - low) / 2;
if (isPossible(arr, k, w, mid)) {
ans = Math.Max(ans, mid);
low = mid + 1;
} else {
high = mid - 1;
}
}
return ans;
}
static void Main(string[] args) {
int[] arr = {2, 3, 4, 5, 1};
int k = 2;
int w = 2;
Console.WriteLine(maxMinHeight(arr, k, w));
}
}
function isPossible(arr, k, w, maxHeight) {
let n = arr.length;
let water = new Array(n).fill(0);
for (let i = 0; i < n; i++) {
// Add previous watering effect
if (i > 0) {
water[i] = water[i - 1];
}
let currHeight = arr[i] + water[i];
// Remove watering effect beyond window w
if (i >= w) {
currHeight -= water[i - w];
}
// If current height is less than required
if (currHeight < maxHeight) {
let add = maxHeight - currHeight;
water[i] += add;
k -= add;
// If days become negative, not possible
if (k < 0) {
return false;
}
}
}
return true;
}
function maxMinHeight(arr, k, w) {
let n = arr.length;
// Find minimum height manually
let low = arr[0];
for (let i = 1; i < n; i++) {
if (arr[i] < low) {
low = arr[i];
}
}
let high = low + k;
let ans = low;
// Binary Search on the answer
while (low <= high) {
let mid = Math.floor(low + (high - low) / 2);
if (isPossible(arr, k, w, mid)) {
ans = Math.max(ans, mid);
low = mid + 1;
} else {
high = mid - 1;
}
}
return ans;
}
// Driver code
let arr = [2, 3, 4, 5, 1];
let k = 2;
let w = 2;
console.log(maxMinHeight(arr, k, w));
Output
2
Time Complexity: O(n*log(m)), where n is the number of flowers and m is size of search space (minimum height + k).
Space Complexity: O(n), for the auxiliary water array used to track watering effects.