Skip to content

Commit 62fa864

Browse files
committed
optimal bst.
1 parent cf607df commit 62fa864

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

python/dynamic/optimal_bst.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
Problem Statement
3+
=================
4+
5+
Given a sorted array keys[0.. n-1] of search keys and an array freq[0.. n-1] of frequency counts, where freq[i] is the
6+
number of searches to keys[i]. Construct a binary search tree of all keys such that the total cost of all the searches
7+
is as small as possible.
8+
9+
Video
10+
-----
11+
* https://youtu.be/hgA4xxlVvfQ
12+
13+
Analysis
14+
--------
15+
* Recursive: Exponential O(n^n)
16+
* Dynamic Programming: O(n^3)
17+
18+
Reference
19+
---------
20+
* http://www.geeksforgeeks.org/dynamic-programming-set-24-optimal-binary-search-tree/
21+
"""
22+
23+
24+
def min_cost_bst(input_array, freq):
25+
size = rows = cols = len(input_array)
26+
T = [[0 for _ in range(cols)] for _ in range(rows)]
27+
28+
for idx in range(rows):
29+
T[idx][idx] = freq[idx]
30+
31+
for sub_tree_size in range(2, size + 1):
32+
for start in range(size + 1 - sub_tree_size):
33+
end = start + sub_tree_size - 1
34+
T[start][end] = float("inf")
35+
total = sum(freq[start:end + 1])
36+
for k in range(start, end + 1):
37+
val = total + (0 if k - 1 < 0 else T[start][k - 1]) + (0 if k + 1 > end else T[k + 1][end])
38+
T[start][end] = min(val, T[start][end])
39+
40+
return T[0][-1]
41+
42+
43+
def min_cost_bst_recursive_helper(input_array, freq, low_index, high_index, level):
44+
if low_index > high_index:
45+
return 0
46+
min_value = float("inf")
47+
48+
for index in range(low_index, high_index + 1):
49+
val = (min_cost_bst_recursive_helper(input_array, freq, low_index, index - 1, level + 1) # left tree
50+
+ level * freq[index] # value at level
51+
+ min_cost_bst_recursive_helper(input_array, freq, index + 1, high_index, level + 1)) # right tree
52+
min_value = min(val, min_value)
53+
54+
return min_value
55+
56+
57+
def min_cost_bst_recursive(input_array, freq):
58+
return min_cost_bst_recursive_helper(input_array, freq, 0, len(input_array) - 1, 1)
59+
60+
61+
if __name__ == '__main__':
62+
input_array = [10, 12, 16, 21]
63+
freq = [4, 2, 6, 3]
64+
expected = 26
65+
assert expected == min_cost_bst(input_array, freq)
66+
assert expected == min_cost_bst_recursive(input_array, freq)
67+
input_array = [10, 12, 20, 35, 46]
68+
freq = [34, 8, 50, 21, 16]
69+
expected = 232
70+
assert expected == min_cost_bst(input_array, freq)
71+
assert expected == min_cost_bst_recursive(input_array, freq)

0 commit comments

Comments
 (0)