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));
[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));
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem