看到很多写Recover Binary Search Tree这道题的文章都用中序递归来做,我在这里告诉大家,这样做的空间复杂度也是O(n)的,所以虽然他们的答案虽然通过了,但还是没有符合题目的要求,O(1)空间复杂度遍历二叉树的一种算法是morris遍历,详见这里
以下为python的代码
基本思想为中序遍历找到两个非法节点,最后做交换
class Solution:
def __init__(self):
#第一个出错的节点
self.firstnode = None
#第二个出错的节点
self.secondnode = None
#中序遍历的前一个节点
self.pre = None
# @param root, a tree node
# @return a tree node
#morris遍历,空间复杂度为O(1)
def recoverTree(self, root):
if root is None:
return root
result = root
while root is not None:
if root.left is None:
if self.pre is None:
self.pre = root
elif self.pre.val > root.val:
#这里是借鉴而来,还不明白为什么要这样做,但结果确实是对的
if self.firstnode is None:
self.firstnode = self.pre
self.secondnode = root
self.pre = root
root = root.right
else:
tmp = root.left
while tmp.right is not None and tmp.right != root:
tmp = tmp.right
if tmp.right is None:
tmp.right = root
root = root.left
else:
if self.pre.val > root.val:
if self.firstnode is None:
self.firstnode = self.pre
self.secondnode = root
tmp.right = None
self.pre = root
root = root.right
tmp = self.firstnode.val
self.firstnode.val = self.secondnode.val
self.secondnode.val = tmp
return result