Skip to content

Commit 2ee868a

Browse files
committed
no message
1 parent 85a1dea commit 2ee868a

3 files changed

+132
-1
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""
2+
inorder: [LEFT]root[RIGHT]
3+
postorder: [LEFT][RIGHT]root
4+
5+
First thing we know is the value of root, which is the last element of `postorder`.
6+
Find the index of the root in `inorder`. So find out the interval of [LEFT] and [RIGHT] in `inorder`.
7+
8+
The length of the [LEFT] and [RIGHT] in `inorder` are the same with the length of the [LEFT] and [RIGHT] in `postorder`.
9+
"""
10+
class Solution(object):
11+
def buildTree(self, inorder, postorder):
12+
if not inorder or not postorder: return None
13+
14+
root = TreeNode(postorder[-1])
15+
if len(inorder)==1: return root
16+
17+
r = inorder.index(root.val)
18+
19+
leftInOrder = inorder[:r]
20+
leftPostOrder = postorder[:r]
21+
rightInOrder = inorder[r+1:]
22+
rightPostOrder = postorder[r:len(postorder)-1]
23+
24+
root.left = self.buildTree(leftInOrder, leftPostOrder)
25+
root.right = self.buildTree(rightInOrder, rightPostOrder)
26+
27+
return root
28+
"""
29+
Time: O(NLogN). For each node, we need to do an iteration to its children. To be precise..
30+
O(N) for constructing root.
31+
32+
O(N/2) for constructing root.left
33+
O(N/2) for constructing root.right
34+
35+
O(N/4) for constructing root.left.left
36+
O(N/4) for constructing root.left.right
37+
O(N/4) for constructing root.right.left
38+
O(N/4) for constructing root.right.right
39+
...
40+
41+
To improve this, we can use a hash table to get the index of `i` below
42+
43+
44+
Space: O(NLogN).
45+
For each node, we need to construct inorder/postorder arrays of its children.
46+
We can improve this by using pointers.
47+
"""
48+
49+
"""
50+
Improved version.
51+
Time: O(N).
52+
Space: O(N). For `index`.
53+
"""
54+
class Solution(object):
55+
def buildTree(self, inorder, postorder):
56+
def helper(i, j, k, l):
57+
if j-i<=0: return None
58+
if l-k<=0: return None
59+
60+
root = TreeNode(postorder[l-1])
61+
if j-i==1: return root
62+
63+
r = index[root.val]
64+
65+
root.left = helper(i, r, k, k+r-i)
66+
root.right = helper(r+1, j, k+r-i, l-1)
67+
return root
68+
69+
index = {} #the index of inorder
70+
for i, n in enumerate(inorder): index[n] = i
71+
return helper(0, len(inorder), 0, len(postorder))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
Time: O(N)
3+
Space: O(N)
4+
5+
preorder: root[LEFT][RIGHT]
6+
inorder: [LEFT]root[RIGHT]
7+
8+
The `helper()` will return the root node from `preorder` and `inorder`.
9+
If they have left or right child, call `helper()` again to get the left or right node.
10+
11+
Use pointers to represent array, avoiding keep copying `preorder` and `inorder`.
12+
i and j represent the preorder[i:j]
13+
k and l epresent the inorder[k:l]
14+
"""
15+
class Solution(object):
16+
def buildTree(self, preorder, inorder):
17+
def helper(i, j, k, l):
18+
root = TreeNode(preorder[i])
19+
20+
r = inorderIndex[root.val] #the index of the root val in inorder
21+
leftLength = r-k
22+
rightLength = l-(r+1)
23+
24+
if leftLength>0: root.left = helper(i+1, i+1+leftLength, k, k+leftLength)
25+
if rightLength>0: root.right = helper(i+1+leftLength, i+1+leftLength+rightLength, r+1, r+1+rightLength)
26+
return root
27+
28+
inorderIndex = {}
29+
for i, n in enumerate(inorder): inorderIndex[n] = i
30+
return helper(0, len(preorder), 0, len(inorder))

problems/convert-sorted-array-to-binary-search-tree.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,34 @@ def sortedArrayToBST(self, nums):
1919
2020
Time: O(N). Because there will be N element being construct.
2121
Space: O(LogN). There will be LogN level of recursive call.
22-
"""
22+
"""
23+
24+
25+
26+
"""
27+
Time: O(N)
28+
Space: O(LogN)
29+
30+
To make it height-balanced
31+
We need to make sure that the number of nodes in left substree and right subtree be the same.
32+
Since the `nums` is already sorted, the best nodes to be root is the one in the middle.
33+
34+
`helper()` will get the root node from the nums[i:j].
35+
If it has left child, it will recursively call `helper()` to get the child.
36+
37+
Use pointers i and j as param to avoid keep copying `nums`.
38+
"""
39+
class Solution(object):
40+
def sortedArrayToBST(self, nums):
41+
def helper(i, j):
42+
m = (i+j)/2
43+
node = TreeNode(nums[m])
44+
45+
leftLength = m-i #number of nodes in the left subtree
46+
rightLength = j-(m+1) #number of nodes in the right subtree
47+
48+
if leftLength>0: node.left = helper(i, m)
49+
if rightLength>0: node.right = helper(m+1, j)
50+
return node
51+
52+
return helper(0, len(nums))

0 commit comments

Comments
 (0)