力扣学习-DFS

99. 恢复二叉搜索树

题目:

二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。

示例:

输入: [1,3,null,null,2]
1
/
3
\
2
输出: [3,1,null,null,2]
3
/
1
\
2

思路:

指针数组交换法
因为题目中说树中只有两个点错了,所以我们其实只要交换这两个节点的值就ok了。方法先设一个指针数组err,保存节点的指针,找到出现错误的两个点后(寻找方法后面说),我们把这两个节点的指针保存进指针数组中,最后我们将指针数组中两个指针的值进行一下交换即完成错误节点的修正。
错误点的寻找:
使用非递归方法中序遍历二叉树,但是我们在遍历过程中并不保存所有的节点,我们需要的定义一个新的指针prev指向左边节点,由中序遍历栈的pop可知,旧指针cur用来指向右边节点,如果当前指针cur的值小于prev的值,即左边节点的值>右边节点的值,说明这两个点有一个是错误点,然后我们根据下面这句代码将错误点保存进指针数组:

if prev and prev.val>cur.val:#如果右边节点没有左边节点大
	err[0]=prev if not err[0] else err[0]
	err[1]=cur

这里要判断err[0]中是否有值,因为是中序遍历,而且只有两个错误点,所以无值说明当前是左边错误点,有值说明我们已经找到左边的点了,我们只须遍历找到右边错误节点即可,左边点已经确定不能变化了。如果不进行判断,那么随着我们遍历到右边的指针,err中的左边指针肯定会变为和右边有错的分错误点,而不是整体的左错误点
(另外可以中序遍历将树的非空节点指针保存在一个数组a中,然后将树的值保存在一个数组b中,然后我们对数组b进行排序,因为是中序遍历,且错误原因是树中节点的顺序错了,所以将数组a中每个指针的值变为排序后b中对应的值即完成树的修正。)

代码:
class Solution:
    def recoverTree(self, root: TreeNode) -> None:
        if not root:
            return 
        err=[None, None]#保存的是指针
        st=[]
        cur=root
        prev=None
        while cur or st:
            if cur:
                st.append(cur)
                cur=cur.left
            else:
                cur=st.pop()#cur右边节点
                if prev and prev.val>cur.val:#如果右边节点没有左边节点大
                    err[0]=prev if not err[0] else err[0]
                    err[1]=cur
                prev=cur#左边节点
                cur=cur.right
        #通过将指针的val修改进而改变整棵树        
        err[0].val, err[1].val = err[1].val, err[0].val
        return

你可能感兴趣的:(On,the,Way,沟沟道道)