-
Notifications
You must be signed in to change notification settings - Fork 0
/
lca.rb
152 lines (120 loc) · 2.85 KB
/
lca.rb
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
class Node
attr_reader :val
attr_reader :left
attr_reader :right
def initialize(val, left, right)
@val = val
@left = left
@right = right
end
def lca(val_one, val_two)
return nil if @left.nil? || @right.nil?
return @left.lca(val_one, val_two) if val_one < @val && val_two < @val
return self if val_one < @val && @val < val_two && @left.find_node(val_one) && @right.find_node(val_two)
return @right.lca(val_one, val_two) if @val < val_one && @val < val_two
end
def find_node(val)
return self if @val == val
return @left.find_node(val) if [email protected]? && val < @val
return @right.find_node(val) if [email protected]? && @val < val
return nil
end
end
def assert(test_name, actual, expected)
puts "#{test_name}:"
if actual != expected
puts "Failed: expected #{expected} but was #{actual}"
else
puts "Passed"
end
end
# 10
# / \
# 5 12
#
def it_finds_trivial_root_node
left = Node.new(5, nil, nil)
right = Node.new(12, nil, nil)
root = Node.new(10, left, right)
assert("it_finds_trivial_root_node", root.find_node(10), root)
end
it_finds_trivial_root_node()
# 10
# / \
# 5 12
#
def it_finds_leaf_node
left = Node.new(5, nil, nil)
right = Node.new(12, nil, nil)
root = Node.new(10, left, right)
assert("it_finds_leaf_node", root.find_node(5), left)
end
it_finds_leaf_node()
# 10
# / \
# 5 12
# \
# 15
# \
# 20
def it_finds_deeply_nested_leaf_node
left = Node.new(5, nil, nil)
two = Node.new(20, nil, nil)
one = Node.new(15, nil, two)
right = Node.new(12, nil, one)
root = Node.new(10, left, right)
assert("it_finds_deeply_nested_leaf_node", root.find_node(20), two)
end
it_finds_deeply_nested_leaf_node()
# 10
# / \
# 5 12
#
def it_returns_nil_if_node_not_found
left = Node.new(5, nil, nil)
right = Node.new(12, nil, nil)
root = Node.new(10, left, right)
assert("it_returns_nil_if_node_not_found", root.find_node(16), nil)
end
it_returns_nil_if_node_not_found()
# 10
# / \
# 5 12
#
def it_finds_trivial_lca
left = Node.new(5, nil, nil)
right = Node.new(12, nil, nil)
root = Node.new(10, left, right)
assert("it_finds_trivial_lca", root.lca(5, 12).val, 10)
end
#it_finds_trivial_lca()
# 10
# / \
# 5 12
# / \
# 11 15
#
def it_finds_first_level_lca
one = Node.new(5, nil, nil)
three = Node.new(11, nil, nil)
four = Node.new(15, nil, nil)
two = Node.new(12, three, four)
root = Node.new(10, one, two)
assert("it_finds_first_level_lca", root.lca(11, 15).val, 12)
end
#it_finds_first_level_lca()
# 10
# / \
# 5 12
# / \
# 11 15
#
def it_returns_nil_if_no_lca
one = Node.new(5, nil, nil)
three = Node.new(11, nil, nil)
four = Node.new(15, nil, nil)
two = Node.new(12, three, four)
root = Node.new(10, one, two)
assert("it_returns_nil_if_no_lca", root.lca(11, 16), nil)
end
it_returns_nil_if_no_lca()