恢复二叉搜索树
题目描述:
解题思路:
- 第一种:递归思路。对于树的题几乎都可以通过递归来实现,那么这道题我们还是使用递归的方法来解。这一题从题目中可以get到信息点就是错误的只有两个数字,我们只需要找到这两个数字然后换位置就可以了,那现在的问题就是要怎么找到这两个数。首先,我们设了两个值来代表这两个错误的数,还有一个
temp
来保存前一个结点的值。作为二叉搜索树,如果有左结点,那么左子树上所有结点的值均小于等于它的根结点的值,所以我们通过递归,找到所有左子树,直到左子树为空,后面然后将当前结点元素分别和前一个节点元素,也就是最左的结点比较大小,如果大了,则说明这个节点元素就是第一个出错的元素,将这个数记录下来。下面找第二个出错元素,我们继续递归,直到最后一个数使得self.temp.val > tree.val
,也就是出错,就是第二个出错元素。 - 时间复杂度:O(N)
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def __init__(self):
self.r1, self.r2 = None, None
self.temp = None
def recoverTree(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root:
return None
self.check_Tree(root)
self.r1.val, self.r2.val = self.r2.val, self.r1.val
def check_Tree(self, tree):
if tree:
self.check_Tree(tree.left)
if self.temp and self.temp.val > tree.val:
if not self.r1:
self.r1 = self.temp
self.r2 = tree
self.temp = tree
self.check_Tree(tree.right)
-
第二种:中序遍历迭代法。这个方法就比较厉害了,我们通过观察发现,二叉搜索树中序遍历输出是递增的,所以我们在遍历二叉树的过程中只要找到不满足递增的点(即错误交换的点),然后交换两者的值就解决问题了。
-
时间复杂度:O(N)
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def recoverTree(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root:
return None
temp = TreeNode(-float('inf'))
r1, r2 = None, None
stack = []
tree = root
while stack or tree:
while tree:
stack.append(tree)
tree = tree.left
c_node = stack.pop()
if c_node.val > temp.val: # 根据当前节点和前一个节点的值来判断节点是否错误
temp = c_node
else:
if not r1:
r1 = temp
r2 = c_node
else:
r2 = c_node
if c_node.right:
tree = c_node.right
r1.val, r2.val = r2.val, r1.val # 交换两个错误交换的节点