forked from MTrajK/coding-problems
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfind_second_largest_node_bst.py
More file actions
110 lines (86 loc) · 3.3 KB
/
find_second_largest_node_bst.py
File metadata and controls
110 lines (86 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
'''
Find second largest node in bst
Given the root to a binary search tree, find the second largest node in the tree.
=========================================
There are 4 possible cases (see the details in the code).
Only 1 branch is searched to the end (leaf), not the whole tree.
Time Complexity: O(N) , this is the worst case when all elements are in one (the right) branch O(N), O(LogN) if the tree is balanced (balanced bst)
Space Complexity: O(N) , because of the recursion stack (but this is if the tree is one branch), O(LogN) if the tree is balanced.
The second solution is simpler and it's same as find_kth_smallest_node_bst.py but K is 2.
Time Complexity: O(N)
Space Complexity: O(N)
'''
##############
# Solution 1 #
##############
# import TreeNode class from tree_helpers.py
from tree_helpers import TreeNode
def find_second_largest_bst_1(root):
if root == None:
return None
return search_1(root, False)
def search_1(node, visited_left):
# the right child is bigger than the current node
if node.right is not None:
result = search_1(node.right, visited_left)
if result is None:
# return this node, because the bottom is reached and the leaf is bigger than this node
return node
# result node is found
return result
# if this node is a part of the left subtree and this node doesn't have right child
# then this is the solution
if visited_left:
return node
# go to the left subtree
# the current node is bigger than all nodes in the left subtree, search for the biggest one there
if node.left is not None:
return search_1(node.left, True)
# this is a tree leaf (the right most element)
return None
##############
# Solution 2 #
##############
def find_second_largest_bst_2(root):
return search_2(root, 2)[1]
def search_2(node, k):
if node == None:
return (k, None)
# check right
right = search_2(node.right, k)
if right[0] == 0:
return right
# check current node
k = right[0] - 1
if k == 0:
return (0, node)
# check left
return search_2(node.left, k)
###########
# Testing #
###########
# Test 1
# Correct result => 10
tree = TreeNode(5, TreeNode(3, TreeNode(1), TreeNode(4)), TreeNode(8, TreeNode(7), TreeNode(12, TreeNode(10, TreeNode(13)))))
print(find_second_largest_bst_1(tree).val)
print(find_second_largest_bst_2(tree).val)
# Test 2
# Correct result => 8
tree = TreeNode(5, TreeNode(3, TreeNode(1), TreeNode(4)), TreeNode(8, TreeNode(7), TreeNode(12)))
print(find_second_largest_bst_1(tree).val)
print(find_second_largest_bst_2(tree).val)
# Test 3
# Correct result => 4
tree = TreeNode(5, TreeNode(3, TreeNode(1), TreeNode(4)))
print(find_second_largest_bst_1(tree).val)
print(find_second_largest_bst_2(tree).val)
# Test 4
# Correct result => 7
tree = TreeNode(5, TreeNode(3, TreeNode(1), TreeNode(4)), TreeNode(8, TreeNode(6, None, TreeNode(7))))
print(find_second_largest_bst_1(tree).val)
print(find_second_largest_bst_2(tree).val)
# Test 5
# Correct result => 11
tree = TreeNode(5, TreeNode(3, TreeNode(1), TreeNode(4)), TreeNode(8, TreeNode(7), TreeNode(12, TreeNode(9, None, TreeNode(10, None, TreeNode(11))))))
print(find_second_largest_bst_1(tree).val)
print(find_second_largest_bst_2(tree).val)