Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Minimum Cost Tree From Leaf Values in Python
The Minimum Cost Tree From Leaf Values problem asks us to build a binary tree from an array where each leaf corresponds to array elements in order, and each internal node's value equals the product of the maximum leaf values in its left and right subtrees. We need to find the minimum sum of all internal node values.
Given an array of positive integers, we must construct binary trees such that:
- Each node has either 0 or 2 children
- Array values correspond to leaf values in an inorder traversal
- Each non-leaf node equals the product of the largest leaf value in its left and right subtrees
For example, with array [6,2,4], the output is 32. Here's why:
Dynamic Programming Solution
We'll use dynamic programming with memoization to solve this efficiently ?
class Solution:
def mctFromLeafValues(self, arr):
self.memo = {}
def dp(i, j):
# Base case: no internal nodes needed
if j <= i:
return 0
# Return cached result
if (i, j) in self.memo:
return self.memo[(i, j)]
res = float('inf')
# Try all possible split points
for k in range(i, j):
left_cost = dp(i, k)
right_cost = dp(k + 1, j)
# Cost of current internal node
left_max = max(arr[i:k+1])
right_max = max(arr[k+1:j+1])
current_cost = left_max * right_max
total_cost = left_cost + right_cost + current_cost
res = min(res, total_cost)
self.memo[(i, j)] = res
return res
return dp(0, len(arr) - 1)
# Test the solution
solution = Solution()
arr = [6, 2, 4]
result = solution.mctFromLeafValues(arr)
print(f"Input: {arr}")
print(f"Minimum cost: {result}")
Input: [6, 2, 4] Minimum cost: 32
How It Works
The algorithm uses dynamic programming where dp(i, j) represents the minimum cost to build a tree from array elements between indices i and j:
- Base case: If j ? i, no internal nodes needed, return 0
- Recursive case: Try all possible split points k between i and j
- Cost calculation: Sum of left subtree cost + right subtree cost + current node cost
- Memoization: Cache results to avoid redundant calculations
Alternative Example
# Test with different array
solution = Solution()
test_cases = [
[6, 2, 4],
[4, 11],
[1, 3, 2, 5]
]
for arr in test_cases:
result = solution.mctFromLeafValues(arr)
print(f"Array: {arr} ? Minimum cost: {result}")
Array: [6, 2, 4] ? Minimum cost: 32 Array: [4, 11] ? Minimum cost: 44 Array: [1, 3, 2, 5] ? Minimum cost: 40
Time and Space Complexity
- Time Complexity: O(n³) where n is the length of the array
- Space Complexity: O(n²) for memoization storage
Conclusion
The dynamic programming approach efficiently finds the minimum cost tree by trying all possible tree structures and caching intermediate results. The key insight is breaking the problem into smaller subproblems representing subtrees.
