leetcode_99. 恢复二叉搜索树

目录

一、题目内容

二、解题思路

三、代码


一、题目内容

二叉搜索树中的两个节点被错误地交换。

请在不改变其结构的情况下,恢复这棵树。

示例 1:

输入: [1,3,null,null,2]

   1
  /
 3
  \
   2

输出: [3,1,null,null,2]

   3
  /
 1
  \
   2

示例 2:

输入: [3,1,4,null,null,2]

  3
 / \
1   4
   /
  2

输出: [2,1,4,null,null,3]

  2
 / \
1   4
   /
  3

进阶:

使用 O(n) 空间复杂度的解法很容易实现。
你能想出一个只使用常数空间的解决方案吗?

二、解题思路

中序遍历二叉搜索树则可以得到一个递增的序列,因此如果在这个序列中出现了两个数字交换,则大的数一定换到了小的数的位置,因此之后大的数和大的数之后的数组成了一个降序对,因此第一个降序对中的大数就是那个被换的数,但是和哪个换的就不知道了,因此还需要往后找。

再看小的数,因为被换到了后面,因此这个小的数比它现在位置之前的那个数要小,因此可以得到第二个降序对,因而第二个降序对里小的数就是那个和已经确定的大的数交换的。

因此中序遍历完成后,把得到的大数和小数交换即可恢复二叉搜索树。

例如:

[1,2,3,4,5,6]

3和6交换:

[1,2,6,4,5,3]

第一个降序对:

[6,4]

第二个降序对:

[5,3]

3确实比4和5小,因此记录6这个大数,再找到3这个小数交换即可,不然不是递增的。

三、代码

# 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

    def __repr__(self):
        return str(self.val)

class Solution:
    def __init__(self):
        self.large = None
        self.small = None
        self.pre = None
    def recoverTree(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        self.inorder(root)
        temp = self.large.val
        self.large.val = self.small.val
        self.small.val = temp


    def inorder(self, root):
        if not root:
            return
        self.inorder(root.left)

        if self.pre is not None and self.pre.val > root.val:
            if self.large is None:  # 找到了第一个大数
                self.large = self.pre
            self.small = root  # 一直找小数
        self.pre = root
        self.inorder(root.right)

if __name__ == '__main__':
    a = TreeNode(1)
    a.left = TreeNode(3)
    a.left.right = TreeNode(2)

    s = Solution()
    s.recoverTree(a)
    print(a)
悲恋花丶无心之人 CSDN认证博客专家 深度学习 神经网络 Pytorch
计算机视觉在读研究生,熟悉Pytorch,MXNet,TensorFlow,Keras等深度学习框架,主要涉及的领域有目标检测,语义分割,超分辨率重建,行人重识别等。
个人GitHub网址为:https://github.com/nickhuang1996
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值