Skip to content

Commit 5b14f61

Browse files
committed
solve Inorder Successor in BST II
1 parent 9fd122f commit 5b14f61

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Definition for a Node.
2+
class Node:
3+
def __init__(self, val):
4+
self.val = val
5+
self.left = None
6+
self.right = None
7+
self.parent = None
8+
9+
10+
class Solution:
11+
# Straight Forward In-Order DFS.
12+
#
13+
# Time: O(n) time, where n is the number of nodes.
14+
# Space: O(n) additional space, due to recursion call stack in worst case.
15+
#
16+
# Consider the tree:
17+
# 4
18+
# 2 6
19+
# 1 3 5 7
20+
# If node = Node(5,...), then return Node(6,...).
21+
#
22+
def inorderSuccessor(self, node: "Node") -> "Node":
23+
# search for the root
24+
root = node
25+
while root.parent:
26+
root = root.parent
27+
28+
found = False
29+
30+
def inorder_dfs(curr_node: "Node") -> "Node":
31+
nonlocal found
32+
33+
if not curr_node:
34+
return None
35+
36+
found_node_left = inorder_dfs(curr_node=curr_node.left)
37+
if found_node_left is not None:
38+
return found_node_left
39+
40+
if found:
41+
return curr_node
42+
43+
if curr_node == node:
44+
found = True
45+
46+
found_node_right = inorder_dfs(curr_node=curr_node.right)
47+
if found_node_right is not None:
48+
return found_node_right
49+
50+
return inorder_dfs(curr_node=root)
51+
52+
53+
class SolutionTwo:
54+
# There is O(1) space solution.
55+
# Time: O(H) i.e. O(lgN) in average case, and O(N) in worst case.
56+
# Space: O(1)
57+
#
58+
# Case wise:
59+
# 1. Node has right subtree.
60+
# In this case, keep going left. The left-most node (leaf or without right
61+
# subtree is the successor).
62+
# 2. Node has no right subtree.
63+
# In this case, successor is up in the tree or None.
64+
# Keep going up along the right branches, until we encounter a left branch.
65+
# The parent of the left branch is the successor.
66+
def inorderSuccessor(self, node: Node):
67+
if node.right is not None:
68+
node = node.right
69+
while node.left:
70+
node = node.left
71+
return node
72+
73+
# case when node has no right subtree
74+
# move up along right branches
75+
while node.parent and node.parent.right == node:
76+
node = node.parent
77+
# either None or curr.parent.left == curr
78+
return node.parent
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import unittest
2+
3+
from inorder_successor_in_bst_ii import Node, Solution, SolutionTwo
4+
5+
6+
class TestInorderSuccessorInBSTII(unittest.TestCase):
7+
def test_example_1(self):
8+
root = Node(val=2)
9+
root.left = Node(val=1)
10+
root.left.parent = root
11+
root.right = Node(val=3)
12+
root.right.parent = root
13+
14+
assert Solution().inorderSuccessor(node=root.left) == root
15+
assert SolutionTwo().inorderSuccessor(node=root.left) == root
16+
17+
def test_example_2(self):
18+
assert Solution().inorderSuccessor(node=Node(val=0)) is None
19+
assert SolutionTwo().inorderSuccessor(node=Node(val=0)) is None

0 commit comments

Comments
 (0)