Maximizing Smallest Flower Height in Garden with Watering Constraint

Last Updated : 25 Jun, 2025

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

Try It Yourself
redirect icon

[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.

C++
#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;
}
Java
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));
    }
}
Python
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#
// 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));
    }
}
JavaScript
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 using k days and a watering window of size w. Since the number of required days increases with the target height, the problem has a monotonic property, making binary search an efficient choice.

C++
#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;
}
 
Java
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));
    }
}
Python
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))
C#
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));
    }
}
JavaScript
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.

Comment