16. Equalize the Towers

โœ… GFG solution to the Equalize the Towers problem: find minimum cost to make all towers same height using binary search optimization. ๐Ÿš€

The problem can be found at the following link: ๐Ÿ”— Question Link

๐Ÿงฉ Problem Description

You are given an array heights[] representing the heights of towers and another array cost[] where each element represents the cost of modifying the height of respective tower.

The goal is to make all towers of same height by either adding or removing blocks from each tower. Modifying the height of tower 'i' by 1 unit costs cost[i].

Return the minimum cost to equalize the heights of all towers.

๐Ÿ“˜ Examples

Example 1

Input: heights[] = [1, 2, 3], cost[] = [10, 100, 1000]
Output: 120
Explanation: The heights can be equalized by either "Removing one block from 3 and adding one in 1" or "Adding two blocks in 1 and adding one in 2". Since the cost of operation in tower 3 is 1000, the first process would yield 1010 while the second one yields 120.

Example 2

Input: heights[] = [7, 1, 5], cost[] = [1, 1, 1]
Output: 6
Explanation: The minimum cost to equalize the towers is 6, achieved by setting all towers to height 5.

๐Ÿ”’ Constraints

  • $1 \le \text{heights.size()} = \text{cost.size()} \le 10^5$

  • $1 \le \text{heights}[i] \le 10^4$

  • $1 \le \text{cost}[i] \le 10^3$

โœ… My Approach

The optimal approach uses Binary Search on Answer to find the target height that minimizes the total cost:

Binary Search on Target Height

  1. Search Space Setup:

    • The optimal target height lies between 0 and maximum height in the array.

    • We need to find the height that minimizes the total cost function.

  2. Cost Function Analysis:

    • For any target height h, cost = ฮฃ|heights[i] - h| ร— cost[i]

    • This creates a unimodal function (convex) with a single minimum.

  3. Binary Search Implementation:

    • Compare costs at adjacent heights m and m+1.

    • If cost at m โ‰ค cost at m+1, optimal height is in left half (including m).

    • Otherwise, optimal height is in right half.

  4. Final Calculation:

    • Once we find the optimal height, calculate the actual minimum cost.

๐Ÿ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n ร— log(max_height)), where n is the number of towers and max_height is the maximum height in the array. Binary search takes O(log(max_height)) iterations, and each iteration requires O(n) time to calculate the cost.

  • Expected Auxiliary Space Complexity: O(1), as we only use constant extra space for variables and calculations (excluding the input arrays).

๐Ÿง‘โ€๐Ÿ’ป Code (C++)

class Solution {
public:
    int minCost(vector<int>& heights, vector<int>& cost) {
        int l = 0, h = *max_element(heights.begin(), heights.end());
        while (l < h) {
            int m = l + (h - l) / 2;
            long long c1 = 0, c2 = 0;
            for (int i = 0; i < heights.size(); ++i) {
                c1 += (long long)abs(heights[i] - m) * cost[i];
                c2 += (long long)abs(heights[i] - m - 1) * cost[i];
            }
            c1 <= c2 ? h = m : l = m + 1;
        }
        long long ans = 0;
        for (int i = 0; i < heights.size(); ++i)
            ans += (long long)abs(heights[i] - l) * cost[i];
        return ans;
    }
};
โšก View Alternative Approaches with Code and Analysis

๐Ÿ“Š 2๏ธโƒฃ Ternary Search Approach

๐Ÿ’ก Algorithm Steps:

  1. Use ternary search to find optimal height.

  2. Compare costs at two mid points.

  3. Eliminate one-third of search space each iteration.

class Solution {
public:
    int minCost(vector<int>& heights, vector<int>& cost) {
        int l = 0, h = *max_element(heights.begin(), heights.end());
        while (h - l > 2) {
            int m1 = l + (h - l) / 3, m2 = h - (h - l) / 3;
            long long c1 = 0, c2 = 0;
            for (int i = 0; i < heights.size(); ++i) {
                c1 += (long long)abs(heights[i] - m1) * cost[i];
                c2 += (long long)abs(heights[i] - m2) * cost[i];
            }
            c1 <= c2 ? h = m2 : l = m1;
        }
        long long ans = LLONG_MAX;
        for (int i = l; i <= h; ++i) {
            long long c = 0;
            for (int j = 0; j < heights.size(); ++j)
                c += (long long)abs(heights[j] - i) * cost[j];
            ans = min(ans, c);
        }
        return ans;
    }
};

๐Ÿ“ Complexity Analysis:

  • Time: โฑ๏ธ O(n ร— logโ‚ƒ(max_height))

  • Auxiliary Space: ๐Ÿ’พ O(1)

โœ… Why This Approach?

  • Faster theoretical convergence than binary search.

  • Reduces search space by 1/3 each iteration.

๐Ÿ“Š 3๏ธโƒฃ Weighted Median Approach

๐Ÿ’ก Algorithm Steps:

  1. Sort heights with their costs.

  2. Find weighted median based on cumulative costs.

  3. Direct calculation without search.

class Solution {
public:
    int minCost(vector<int>& heights, vector<int>& cost) {
        vector<pair<int, int>> hc;
        long long total = 0;
        for (int i = 0; i < heights.size(); ++i) {
            hc.push_back({heights[i], cost[i]});
            total += cost[i];
        }
        sort(hc.begin(), hc.end());

        long long sum = 0, ans = 0;
        for (auto& p : hc) {
            sum += p.second;
            if (sum >= (total + 1) / 2) {
                for (int i = 0; i < heights.size(); ++i)
                    ans += (long long)abs(heights[i] - p.first) * cost[i];
                return ans;
            }
        }
        return 0;
    }
};

๐Ÿ“ Complexity Analysis:

  • Time: โฑ๏ธ O(n log n)

  • Auxiliary Space: ๐Ÿ’พ O(n)

โœ… Why This Approach?

  • Mathematically optimal solution.

  • No iterative search required.

๐Ÿ†š ๐Ÿ” Comparison of Approaches

๐Ÿš€ Approach

โฑ๏ธ Time Complexity

๐Ÿ’พ Space Complexity

โœ… Pros

โš ๏ธ Cons

๐Ÿ” Binary Search

๐ŸŸข O(n ร— log(max_height))

๐ŸŸข O(1)

โšก Fastest runtime, minimal ops

๐Ÿงฎ Requires understanding of convexity

๐Ÿ”บ Ternary Search

๐ŸŸข O(n ร— logโ‚ƒ(max_height))

๐ŸŸข O(1)

๐Ÿš€ Faster theoretical convergence

๐Ÿงฎ More complex per iteration

๐Ÿ“Š Weighted Median

๐ŸŸก O(n log n)

๐Ÿ”ธ O(n)

๐ŸŽฏ Mathematically optimal

๐Ÿ’พ Extra space, sorting overhead

๐Ÿ† Best Choice Recommendation

๐ŸŽฏ Scenario

๐ŸŽ–๏ธ Recommended Approach

๐Ÿ”ฅ Performance Rating

โšก Maximum performance, competitive programming

๐Ÿฅ‡ Binary Search

โ˜…โ˜…โ˜…โ˜…โ˜…

๐Ÿš€ Theoretical optimization

๐Ÿฅˆ Ternary Search

โ˜…โ˜…โ˜…โ˜…โ˜†

๐ŸŽฏ Mathematically guaranteed optimal

๐Ÿฅ‰ Weighted Median

โ˜…โ˜…โ˜…โ˜…โ˜†

๐Ÿง‘โ€๐Ÿ’ป Code (Java)

class Solution {
    public int minCost(int[] heights, int[] cost) {
        int l = 0, h = Arrays.stream(heights).max().getAsInt();
        while (l < h) {
            int m = l + (h - l) / 2;
            long c1 = 0, c2 = 0;
            for (int i = 0; i < heights.length; ++i) {
                c1 += (long)Math.abs(heights[i] - m) * cost[i];
                c2 += (long)Math.abs(heights[i] - m - 1) * cost[i];
            }
            if (c1 <= c2) h = m;
            else l = m + 1;
        }
        long ans = 0;
        for (int i = 0; i < heights.length; ++i)
            ans += (long)Math.abs(heights[i] - l) * cost[i];
        return (int)ans;
    }
}

๐Ÿ Code (Python)

class Solution:
    def minCost(self, heights, cost):
        l, h = 0, max(heights)
        while l < h:
            m = l + (h - l) // 2
            c1 = sum(abs(heights[i] - m) * cost[i] for i in range(len(heights)))
            c2 = sum(abs(heights[i] - m - 1) * cost[i] for i in range(len(heights)))
            if c1 <= c2:
                h = m
            else:
                l = m + 1
        return sum(abs(heights[i] - l) * cost[i] for i in range(len(heights)))

๐Ÿง  Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐Ÿ“ฌ Any Questions?. Let's make this learning journey more collaborative!

โญ If you find this helpful, please give this repository a star! โญ


๐Ÿ“Visitor Count

Visitor counter

Last updated