-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy path99.recover-binary-search-tree.py
68 lines (59 loc) · 2.21 KB
/
99.recover-binary-search-tree.py
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
#
# @lc app=leetcode id=99 lang=python3
#
# [99] Recover Binary Search Tree
#
# @lc code=start
# TAGS: Tree, DFS
# Definition for a binary tree node.
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
# Time: O(NlogN). Space: O(N). Sorting
def recoverTree(self, root: TreeNode) -> None:
def inorder(node):
return inorder(node.left) + [node.val] + inorder(node.right) if node else []
values = inorder(root)
sorted_values = sorted(values)
wanted_values = []
for v1, v2 in zip(values, sorted_values):
if v1 != v2:
wanted_values.append(v1)
def recover(node):
if not node: return
if node.val == wanted_values[0]:
node.val = wanted_values[1]
elif node.val == wanted_values[1]:
node.val = wanted_values[0]
recover(node.left)
recover(node.right)
recover(root)
# From article. Time and Space: O(N). Instead of sorting, we find 2 wanted values and switch them.
def recoverTree(self, root: TreeNode) -> None:
def inorder(node):
return inorder(node.left) + [node.val] + inorder(node.right) if node else []
values = inorder(root)
# very clever way to find the 2 values.
# if they are next to each other, then we found them in the first if
# if they are far away each other, then we choose v1 from first occurence and v2 from second occurence. (Because it is sorted.)
x = y = None
for v1, v2 in zip(values, values[1:]):
if v1 > v2:
y = v2
if x is None:
x = v1
else: break
def recover(node, x, y):
if not node: return
if node.val == x:
node.val = y
elif node.val == y:
node.val = x
recover(node.left, x, y)
recover(node.right, x, y)
recover(root, x, y)
# @lc code=end