leetcode 每日一题 99. 恢复二叉搜索树
中序遍历排序
思路:
①按中序遍历树
②确定交换的元素x,y
③再次遍历树,改变对应节点的值
代码:
# 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: def recoverTree(self, root: TreeNode) -> None: """ Do not return anything, modify root in-place instead. """ def inorder(r: TreeNode) -> List[int]: return inorder(r.left) + [r.val] + inorder(r.right) if r else [] def find_two_swapped(nums: List[int]) -> (int, int): n = len(nums) x = y = -1 for i in range(n - 1): if nums[i + 1] < nums[i]: y = nums[i + 1] if x == -1: x = nums[i] else: break return x, y def recover(r: TreeNode, count: int): if r: if r.val == x or r.val == y: r.val = y if r.val == x else x count -= 1 if count == 0: return recover(r.left, count) recover(r.right, count) nums = inorder(root) x, y = find_two_swapped(nums) recover(root, 2)
迭代中序遍历
思路:
通过迭代构造中序遍历,并在一次遍历中找到要交换的节点。
代码:
# 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: def recoverTree(self, root: TreeNode) -> None: """ Do not return anything, modify root in-place instead. """ stack = [] x = y = pred = None while stack or root: while root: stack.append(root) root = root.left root = stack.pop() if pred and root.val < pred.val: y = root if x is None: x = pred else: break pred = root root = root.right x.val, y.val = y.val, x.val
递归中序遍历
思路:
迭代中序遍历可以转换为递归。
代码:
# 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: def recoverTree(self, root: TreeNode) -> None: """ Do not return anything, modify root in-place instead. """ def find_two_swapped(root: TreeNode): nonlocal x, y, pred if root is None: return find_two_swapped(root.left) if pred and root.val < pred.val: y = root if x is None: x = pred 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
线索二叉树
思路:
参考94.二叉树的中序遍历中的不改变树结构的线索二叉树。
代码:
# 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: def recoverTree(self, root: TreeNode) -> None: """ Do not return anything, modify root in-place instead. """ x = y = predecessor = pred = None while root: if root.left: predecessor = root.left while predecessor.right and predecessor.right != root: predecessor = predecessor.right if predecessor.right is None: predecessor.right = root root = root.left else: if pred and root.val < pred.val: y = root if x is None: x = pred pred = root predecessor.right = None root = root.right else: if pred and root.val < pred.val: y = root if x is None: x = pred pred = root root = root.right x.val, y.val = y.val, x.val