# 递归 前序遍历,根结点 ---> 左子树 ---> 右子树。 defPreOrder(self, root): """ Pre-Order Traversal of binary tree :param root: root node of target binary tree :return: TreeNode """ # if not root: return [] # 不处理None模式的一行代码 ifnot root: return [None] # 不处理None模式的一行代码 res = [root.val] left_tree = self.PreOrder(root.left) right_tree = self.PreOrder(root.right) return res + left_tree + right_tree # 如果是递归调用二叉(搜索)树,前/中/后序遍历只用改这里的顺序就行。
classSolution: deffind_two_swapped(self, nums: List[int]) -> (int, int): n = len(nums) x = y = -1# x指的是被移到前面的那个大的数,y指的是被移到后面的那个小的数。 for i inrange(n - 1): if nums[i + 1] < nums[i]: y = nums[i + 1] # y照常后移 # first swap occurence # 第一次出现节点交换 if x == -1: x = nums[i] # second swap occurence # 第二次出现交换节点,无论节点在哪个位置进行了交换,在这个大体上有序的序列中,都只会出现两次降序,所以x锁定第一次降序的首位数字,y照常后移,锁定第一次或者第二次降序的末尾数即可。 else: break return x, y
# 递归 中序遍历,左子树---> 根结点 ---> 右子树。 defInOder(self, root): """ In-Order Traversal of binary tree :param root: root node of target binary tree :return: TreeNode """ # if not root: return [] # 不处理None模式的一行代码 ifnot root: return [None] # 不处理None模式的一行代码 res = [root.val] left_tree = self.InOder(root.left) right_tree = self.InOder(root.right) return left_tree + res + right_tree
defrecoverTree(self, root: TreeNode) -> None: """ Do not return anything, modify root in-place instead. """ # step1:中序遍历得到结果 res = self.InOder(root) for i in res: if i == None: res.remove(None)
# step2:根据二叉搜索树中序遍历递增的特点,找到中序遍历结果中降序的部分,进而找到x和y。 x, y = self.find_two_swapped(res)
# step3:交换x和y节点,直接修改val就行,注意遇到None部分直接continue。 queue = [] queue.append(root) flag_x = flag_y = False whilelen(queue): t = queue.pop(0) if t == None: continue if flag_x and flag_y: break ifnot flag_x and t.val == x: t.val = y flag_x = True elifnot flag_y and t.val == y: t.val = x flag_y = True queue.append(t.left) queue.append(t.right) return root
classSolution: defrecoverTree(self, root): """ :type root: TreeNode :rtype: void Do not return anything, modify root in-place instead. """ deffind_two_swapped(root: TreeNode): nonlocal x, y, pred if root isNone: return
find_two_swapped(root.left) if pred and root.val < pred.val: y = root # first swap occurence if x isNone: x = pred # second swap occurence else: return pred = root find_two_swapped(root.right)
x = y = pred = None find_two_swapped(root) x.val, y.val = y.val, x.val
classSolution: defrecoverTree(self, root): """ :type root: TreeNode :rtype: void Do not return anything, modify root in-place instead. """ # predecessor is a Morris predecessor. # In the 'loop' cases it could be equal to the node itself predecessor == root. # pred is a 'true' predecessor, # the previous node in the inorder traversal. x = y = predecessor = pred = None
while root: # If there is a left child # then compute the predecessor. # If there is no link predecessor.right = root --> set it. # If there is a link predecessor.right = root --> break it. if root.left: # Predecessor node is one step left # and then right till you can. predecessor = root.left while predecessor.right and predecessor.right != root: predecessor = predecessor.right
# set link predecessor.right = root # and go to explore left subtree if predecessor.right isNone: predecessor.right = root root = root.left # break link predecessor.right = root # link is broken : time to change subtree and go right else: # check for the swapped nodes if pred and root.val < pred.val: y = root if x isNone: x = pred pred = root
predecessor.right = None root = root.right # If there is no left child # then just go right. else: # check for the swapped nodes if pred and root.val < pred.val: y = root if x isNone: x = pred pred = root