Open In App

Maximize tree height

Last Updated : 11 Dec, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an integer array arr[] tree heights and you need to collect at least B meters of wood by cutting them. You choose a height H, and every tree taller than H is cut down to height H, contributing (arr[i] – H) wood. Your task is to find the maximum value of H such that the total wood collected from all trees taller than H is at least B.

Examples:

Input: arr[] = [20, 10, 5, 17], B = 7
Output: 15
Explanation: Setting H = 15 gives:
Tree 20 -> cut 5 , Tree 10 -> cut 0, Tree 5 -> cut 0, Tree 17 -> cut 2 => Total wood = 5 + 0 + 0 + 2 = 7
Thus, 15 is a valid height. Any height > 15 gives less than 7 wood.

Input: arr[] = [4, 38, 44, 20, 52], B = 20
Output: 38
Explanation: Setting H = 38 gives:
Tree 4 -> 0, Tree 38 -> 0, Tree 44 -> 6, Tree 20 -> 0, Tree 52 -> 14 => Total wood = 6 + 14 = 20.
Thus 38 is the maximum height.

[Naive Approach] Linear Search - O( N x max(arr[i]) ) Time and O(1) Space

A brute-force solution is to try every height H from 0 to the maximum tree height and, for each H, compute the total wood collected as sum of all positive values of ( arr[i] − H). If the wood is at least B, then H is valid. However, this approach is too slow because the maximum height can be up to 1e6, and each height check takes O(N) time, resulting in an overall complexity of O(N x maxheight).

C++
#include <iostream>
#include <vector>
using namespace std;

// Function to find maximum height H using brute force (linear search)
int minCut(vector<int>& a, int n, int B) {

    // Find the maximum tree height
    int maxHeight = 0;

    for (int i = 0; i < n; i++) {
        maxHeight = max(maxHeight, a[i]);
    }

    int answer = 0;

    // Try every possible height H from 0 to maxHeight
    for (int H = 0; H <= maxHeight; H++) {

        long long wood = 0;

        // Calculate total wood collected if cut at height H
        for (int i = 0; i < n; i++) {

            if (a[i] > H) {
                wood += (a[i] - H);
            }

            // Early break if enough wood is already collected
            if (wood >= B) {
                break;
            }
        }

        // If wood >= B, H works -> try higher H
        if (wood >= B) {
            answer = H;
        }

        else {
            // If wood < B, higher H will also fail -> return last valid height
            return answer;
        }
    }

    return answer;
}

 
int main() {

    vector<int> arr = {20, 10, 5, 17};
    int B = 7;
    int n = arr.size();

    cout << minCut(arr, n, B) << endl;

    return 0;
}
Java
class GFG {

    // Function to find maximum height H using brute force (linear search)
    static int minCut(int[] arr, int n, int B) {
        
        // Find the maximum tree height
        int maxHeight = 0;
        
        for (int i = 0; i < n; i++) {
            maxHeight = Math.max(maxHeight, arr[i]);
        }

        int answer = 0;

        // Try every possible height H from 0 to maxHeight
        for (int H = 0; H <= maxHeight; H++) {

            long wood = 0;

            // Calculate total wood collected if cut at height H
            for (int i = 0; i < n; i++) {

                if (arr[i] > H) {
                    wood += (arr[i] - H);
                }

                // Early break if enough wood is already collected
                if (wood >= B) {
                    break;
                }
            }

            // If wood >= b, H works -> try higher H
            if (wood >= B) {
                answer = H;
            }
            
            else {
                
                // If wood < b, higher H will also fail -> return last valid height
                return answer;
            }
        }

        return answer;
    }
 
    public static void main(String[] args) {
        
        int[] arr = {20, 10, 5, 17};
        int B = 7;
        int n = arr.length;

        System.out.println(minCut(arr, n, B));
    }
}
Python
# Function to find maximum height H using brute force (linear search)
def minCut(arr, n, b):

    # Find the maximum tree height
    maxHeight = 0
    for i in range(n):
        maxHeight = max(maxHeight, arr[i])

    answer = 0

    # Try every possible height H from 0 to maxHeight
    for H in range(maxHeight + 1):

        wood = 0

        # Calculate total wood collected if cut at height H
        for i in range(n):

            if arr[i] > H:
                wood += (arr[i] - H)

            # Early break if enough wood is already collected
            if wood >= b:
                break

        # If wood >= b, H is valid -> try higher H
        if wood >= b:
            answer = H
            
        else:
            
            # If wood < b, higher H will also fail
            #return last valid height
            return answer

    return answer
 
if __name__ == "__main__":

    arr = [20, 10, 5, 17]
    B = 7
    n = len(arr)

    print(minCut(arr, n, B)) 
C#
using System;
using System.Collections.Generic;

class GFG
{
    // Function to find maximum height H using brute force (linear search)
    public static int minCut(List<int> a, int n, int B)
    {
        // Find the maximum tree height
        int maxHeight = 0;

        for (int i = 0; i < n; i++)
        {
            maxHeight = Math.Max(maxHeight, a[i]);
        }

        int answer = 0;

        // Try every possible height H from 0 to maxHeight
        for (int H = 0; H <= maxHeight; H++)
        {
            long wood = 0;

            // Calculate total wood collected if cut at height H
            for (int i = 0; i < n; i++)
            {
                if (a[i] > H)
                {
                    wood += (a[i] - H);
                }

                // Early break if enough wood is already collected
                if (wood >= B)
                {
                    break;
                }
            }

            // If wood >= B, H works -> try higher H
            if (wood >= B)
            {
                answer = H;
            }
            
            else
            {
                // If wood < B, higher H will also fail -> return last valid height
                return answer;
            }
        }

        return answer;
    }
 
    static void Main()
    {
        List<int> arr = new List<int> { 20, 10, 5, 17 };
        int B = 7;
        int n = arr.Count;

        Console.WriteLine(minCut(arr, n, B)); 
    }
}
JavaScript
// Function to find maximum height H using brute force (linear search)
function minCut(arr, n, b) {

    // Find the maximum tree height
    let maxHeight = 0;

    for (let i = 0; i < n; i++) {
        maxHeight = Math.max(maxHeight, arr[i]);
    }

    let answer = 0;

    // Try every possible height H from 0 to maxHeight
    for (let H = 0; H <= maxHeight; H++) {

        let wood = 0;

        // Calculate total wood collected if cut at height H
        for (let i = 0; i < n; i++) {

            if (arr[i] > H) {
                wood += (arr[i] - H);
            }

            // Early break if enough wood is already collected
            if (wood >= b) {
                break;
            }
        }

        // If wood >= b, H works -> try higher H
        if (wood >= b) {
            
            answer = H;
        }
        else {
            
            // If wood < b, higher H will also fail -> return last valid height
            return answer;
        }
    }

    return answer;
}


// Driver Code
let arr = [20, 10, 5, 17];
let B = 7;
let n = arr.length;

console.log(minCut(arr, n, B)); 

Output
15

[Expected Approach] Binary Search on Answer - O( N x log max(arr[i]) ) Time and O(1) Space

Since the amount of wood collected decreases as we increase the cutting height H, the function is monotonic. This allows us to apply binary search on the height range [0, max(arr)]. For each mid value, we compute the total wood obtained by cutting trees above mid. If the collected wood is at least B, mid is a valid height and we try a larger value; otherwise, we reduce the search space. The smallest height that fails and the largest height that succeeds meet at the maximum valid cutting height.

How it Works ?

We binary search on the height H:

  • Search range:
    low = 0, high = max(arr)
  • For each mid = (low + high )/2, compute total wood collected:
    wood = sum of all positive values of (arr[i] - h)
  • If wood >= B, we can try higher H -> move right
  • If wood < B, we must reduce H -> move left
  • The maximum valid H is our answer.
C++
#include <iostream>
#include <vector>
using namespace std;

// Helper function: compute wood collected if cut at height H
long long woodCollected(vector<int> &a, int n, int H) {
    
    long long wood = 0;

    for (int i = 0; i < n; i++) {

        if (a[i] > H) {
            wood += (a[i] - H);
        }

        // early break if enough wood collected
        // (we do not check B here, caller will check)
    }

    return wood;
}

// Main function to find maximum height using Binary Search
int minCut(vector<int>& a, int n, int B) {

    int maxHeight = 0;
    for (int i = 0; i < n; i++) {
        maxHeight = max(maxHeight, a[i]);
    }

    int low = 0;
    int high = maxHeight;
    int answer = 0;

    while (low <= high) {

        int mid = low + (high - low) / 2;

        long long wood = woodCollected(a, n, mid);

        if (wood >= B) {
            
            answer = mid;
            
            // try higher
            low = mid + 1;    
        }
        
        else {
            
            // need lower
            high = mid - 1;   
        }
    }

    return answer;
} 

int main() {

    vector<int> arr = {20, 10, 5, 17};
    int B = 7;
    int n = arr.size();

    cout << minCut(arr, n, B) << endl; 
    return 0;
}
Java
class GFG {

    // Helper function: compute wood collected if cut at height H
    static long woodCollected(int[] a, int n, int H) {

        long wood = 0;

        for (int i = 0; i < n; i++) {

            if (a[i] > H) {
                wood += (a[i] - H);
            }

            // early break if enough wood collected
            // (we do not check B here, caller will check)
        }

        return wood;
    }

    // Main function to find maximum height using Binary Search
    static int minCut(int[] a, int n, int B) {

        int maxHeight = 0;
        for (int i = 0; i < n; i++) {
            maxHeight = Math.max(maxHeight, a[i]);
        }

        int low = 0;
        int high = maxHeight;
        int answer = 0;

        while (low <= high) {

            int mid = low + (high - low) / 2;

            long wood = woodCollected(a, n, mid);

            if (wood >= B) {
                
                answer = mid;
                
                // try higher
                low = mid + 1;    
            }
            
            else {
                
                // need lower
                high = mid - 1;   
            }
        }

        return answer;
    }

    public static void main(String[] args) {

        int[] a = {20, 10, 5, 17};
        int B = 7;
        int n = a.length;

        System.out.println(minCut(a, n, B)); 
    }
}
Python
# Helper function: compute wood collected if cut at height H
def woodCollected(a, n, H):

    wood = 0

    for i in range(n):

        if a[i] > H:
            wood += (a[i] - H)

        # early break if enough wood collected
        # (we do not check B here, caller will check)

    return wood


# Main function to find maximum height using Binary Search
def minCut(a, n, B):

    maxHeight = max(a)
    low = 0
    high = maxHeight
    answer = 0

    while low <= high:

        mid = low + (high - low) // 2

        wood = woodCollected(a, n, mid)

        if wood >= B:
            
            answer = mid
            
            # try higher
            low = mid + 1    
        
        else:
            
            # need lower
            high = mid - 1   

    return answer
 
if __name__ == "__main__":

    a = [20, 10, 5, 17]
    B = 7
    n = len(a)

    print(minCut(a, n, B))
C#
using System;
using System.Collections.Generic;

class GFG {

    // Helper function: compute wood collected if cut at height H
    public static long woodCollected(List<int> a, int n, int H) {

        long wood = 0;

        for (int i = 0; i < n; i++) {

            if (a[i] > H) {
                wood += (a[i] - H);
            }

            // early break if enough wood collected
            // (we do not check B here, caller will check)
        }

        return wood;
    }

    // Main function to find maximum height using Binary Search
    public static int minCut(List<int> a, int n, int B) {

        int maxHeight = 0;

        for (int i = 0; i < n; i++) {
            maxHeight = Math.Max(maxHeight, a[i]);
        }

        int low = 0;
        int high = maxHeight;
        int answer = 0;

        while (low <= high) {

            int mid = low + (high - low) / 2;

            long wood = woodCollected(a, n, mid);

            if (wood >= B) {
                
                answer = mid;
                
                // try higher
                low = mid + 1;    
            }
            
            else {
                
                // need lower
                high = mid - 1;   
            }
        }

        return answer;
    }

    static void Main() {

        List<int> a = new List<int> { 20, 10, 5, 17 };
        int B = 7;
        int n = a.Count;

        Console.WriteLine(minCut(a, n, B));
    }
}
JavaScript
// Helper function: compute wood collected if cut at height H
function woodCollected(a, n, H) {

    let wood = 0;

    for (let i = 0; i < n; i++) {

        if (a[i] > H) {
            wood += (a[i] - H);
        }

        // early break if enough wood collected
        // (we do not check B here, caller will check)
    }

    return wood;
}


// Main function to find maximum height using Binary Search
function minCut(a, n, B) {

    let maxHeight = 0;

    for (let i = 0; i < n; i++) {
        maxHeight = Math.max(maxHeight, a[i]);
    }

    let low = 0;
    let high = maxHeight;
    let answer = 0;

    while (low <= high) {

        let mid = low + Math.floor((high - low) / 2);

        let wood = woodCollected(a, n, mid);

        if (wood >= B) {
            
            answer = mid;
            
            // try higher
            low = mid + 1;    
        }
        
        else {
            
            // need lower
            high = mid - 1;   
        }
    }

    return answer;
}


// Driver Code
let a = [20, 10, 5, 17];
let B = 7;
let n = a.length;

console.log(minCut(a, n, B));

Output
15

Article Tags :

Explore