Skip to content

Commit 660c9ec

Browse files
authored
Merge pull request #1254 from akgmage/dev
add reconstruct bst in go
2 parents aa6bc77 + df20d2c commit 660c9ec

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
Reconstruct BST
3+
The pre-order traversal of a Binary Tree is a traversal technique that starts at the tree's root node and visits nodes in the following order:
4+
Current Node
5+
Left Subtree
6+
Right Subtree
7+
8+
Given a non-empty array of integers representing the pre-order traversal of a Binary Search Tree (BST),
9+
write a function that creates the relevant BST and returns its root node.
10+
11+
The input array will contain the values of BST nodes in the order in which these nodes would be visited with a pre-order traversal.
12+
13+
Sample Input: [10, 4, 2, 1, 5, 17, 19, 18]
14+
Sample Output:
15+
10
16+
/ \
17+
4 17
18+
/ \ \
19+
2 5 19
20+
/ /
21+
1 18
22+
23+
Explanation:
24+
25+
Approach 1:
26+
27+
The ReconstructBst function takes a slice preOrderTraversalValues which represents the pre-order traversal of a binary search tree.
28+
It reconstructs the BST using a recursive approach. Here's how the algorithm works:
29+
30+
The base case is defined when the preOrderTraversalValues slice is empty, in which case it returns nil indicating an empty tree.
31+
32+
The first element in the preOrderTraversalValues slice represents the current node value of the BST.
33+
34+
The algorithm finds the index (rightSubTreeRootIdx) where the right subtree starts by iterating over the remaining elements in
35+
the preOrderTraversalValues slice and finding the first value greater than or equal to the current value.
36+
37+
It recursively calls ReconstructBst on the sub-array representing the left subtree (preOrderTraversalValues[1:rightSubTreeRootIdx])
38+
to reconstruct the left subtree.
39+
40+
It recursively calls ReconstructBst on the sub-array representing the right subtree (preOrderTraversalValues[rightSubTreeRootIdx:])
41+
to reconstruct the right subtree.
42+
43+
Finally, it creates a new BST node with the current value, the reconstructed left subtree, and the reconstructed right subtree,
44+
and returns the node.
45+
46+
The algorithm builds the BST in a top-down manner by dividing the pre-order traversal values into left and right subtrees.
47+
It constructs the left subtree first and then the right subtree.
48+
49+
The time complexity of the algorithm is O(n^2) in the worst case, where n is the number of nodes in the BST.
50+
51+
52+
******************************************************************************************
53+
54+
Approach 2:
55+
56+
The ReconstructBst function takes a slice preOrderTraversalValues which represents the pre-order traversal of a binary search tree.
57+
It reconstructs the BST using a range-based approach. Here's how the algorithm works:
58+
59+
The ReconstructBst function initializes a treeInfo struct to keep track of the current root index.
60+
61+
The ReconstructBst function calls the reconstructBSTFromRange helper function, passing the minimum and maximum integer values
62+
as the initial range, the pre-order traversal values, and the treeInfo struct.
63+
64+
The reconstructBSTFromRange function first checks if the current root index has reached the end of the pre-order traversal values.
65+
If so, it returns nil indicating an empty subtree.
66+
67+
It retrieves the value of the current root from the pre-order traversal values.
68+
69+
It checks if the root value is outside the valid range defined by the lower and upper bounds. If so, it returns
70+
71+
The time complexity of the ReconstructBst function is O(n), where n is the number of nodes in the reconstructed BST.
72+
This is because the function processes each node exactly once.
73+
74+
The space complexity of the ReconstructBst function is O(n), where n is the number of nodes in the reconstructed BST.
75+
This is because the function creates BST nodes and recursively calls itself to construct the left and right subtrees.
76+
The space complexity is determined by the height of the BST, which can be at most n in the worst case for a skewed BST.
77+
*/
78+
package main
79+
80+
import "math"
81+
82+
// BST represents a binary search tree node.
83+
type BST struct {
84+
Value int
85+
Left *BST
86+
Right *BST
87+
}
88+
89+
// Approach 1: Time complexity O(n^2) Space O(n), where n is length of input array
90+
// ReconstructBst takes a slice of integers representing the pre-order traversal of a BST and returns the reconstructed BST.
91+
func ReconstructBst(preOrderTraversalValues []int) *BST {
92+
// Base case: If the pre-order traversal is empty, return nil indicating an empty tree.
93+
if len(preOrderTraversalValues) == 0 {
94+
return nil
95+
}
96+
97+
// Get the current value from the pre-order traversal values.
98+
currentVal := preOrderTraversalValues[0]
99+
100+
// Find the index where the right subtree starts by searching for the first value greater than or equal to the current value.
101+
rightSubTreeRootIdx := len(preOrderTraversalValues)
102+
for i := 1; i < len(preOrderTraversalValues); i++ {
103+
value := preOrderTraversalValues[i]
104+
if value >= currentVal {
105+
rightSubTreeRootIdx = i
106+
break
107+
}
108+
}
109+
110+
// Recursively reconstruct the left and right subtrees by calling the ReconstructBst function on the appropriate sub-arrays.
111+
leftSubTree := ReconstructBst(preOrderTraversalValues[1:rightSubTreeRootIdx])
112+
rightSubTree := ReconstructBst(preOrderTraversalValues[rightSubTreeRootIdx:])
113+
114+
// Create a new BST node with the current value and the reconstructed left and right subtrees.
115+
return &BST{Value: currentVal, Left: leftSubTree, Right: rightSubTree}
116+
}
117+
118+
119+
// Approach 2: Time complexity O(n) Space O(n), where n is length of input array
120+
121+
// treeInfo is a helper struct to keep track of the current root index during the reconstruction process.
122+
type treeInfo struct {
123+
rootIdx int
124+
}
125+
126+
// ReconstructBst takes a slice of integers representing the pre-order traversal of a BST and returns the reconstructed BST.
127+
func ReconstructBst2(preOrderTraversalValues []int) *BST {
128+
// Create a treeInfo struct to keep track of the current root index.
129+
treeInfo := &treeInfo{rootIdx: 0}
130+
131+
// Call the helper function to reconstruct the BST from the given range and return the result.
132+
return reconstructBSTFromRange(math.MinInt32, math.MaxInt32, preOrderTraversalValues, treeInfo)
133+
}
134+
135+
// reconstructBSTFromRange reconstructs the BST recursively within the given range using the pre-order traversal values.
136+
func reconstructBSTFromRange(lowerBound, upperBound int, preOrderTraversalValues []int, currentSubtreeInfo *treeInfo) *BST {
137+
// Check if the root index has reached the end of the pre-order traversal values. If so, return nil indicating an empty subtree.
138+
if currentSubtreeInfo.rootIdx == len(preOrderTraversalValues) {
139+
return nil
140+
}
141+
142+
// Get the value of the current root from the pre-order traversal values.
143+
rootValue := preOrderTraversalValues[currentSubtreeInfo.rootIdx]
144+
145+
// Check if the root value is out of the valid range defined by the lower and upper bounds. If so, return nil indicating an invalid subtree.
146+
if rootValue < lowerBound || rootValue >= upperBound {
147+
return nil
148+
}
149+
150+
// Increment the root index to move to the next element in the pre-order traversal values.
151+
currentSubtreeInfo.rootIdx++
152+
153+
// Recursively reconstruct the left subtree within the range (lowerBound, rootValue) using the updated root index.
154+
leftSubtree := reconstructBSTFromRange(lowerBound, rootValue, preOrderTraversalValues, currentSubtreeInfo)
155+
156+
// Recursively reconstruct the right subtree within the range (rootValue, upperBound) using the updated root index.
157+
rightSubtree := reconstructBSTFromRange(rootValue, upperBound, preOrderTraversalValues, currentSubtreeInfo)
158+
159+
// Create a new BST node with the current root value and the reconstructed left and right subtrees.
160+
return &BST{Value: rootValue, Left: leftSubtree, Right: rightSubtree}
161+
}

0 commit comments

Comments
 (0)