【深度优先遍历】力扣 99. 恢复二叉搜索树

恢复二叉搜索树的基础知识与原理

在讨论如何恢复二叉搜索树之前,我们需要先了解二叉搜索树(Binary Search Tree,简称BST)的一些基本概念。二叉搜索树是一种特殊的二叉树,其中每个节点都有以下性质:

  • 对于任意节点 Node,其左子树上所有节点的值都小于 Node 的值。
  • 其右子树上所有节点的值都大于 Node 的值。

中序遍历与二叉搜索树的性质

二叉搜索树的一个重要性质是,如果对其进行中序遍历(Inorder Traversal),即按照“左子树 -> 根节点 -> 右子树”的顺序遍历所有节点,得到的序列是升序排列的。

恢复二叉搜索树的思路

给定一棵二叉搜索树,其中恰好有两个节点的值被错误地交换了,导致整个树不再满足BST的性质。我们的任务是找出这两个节点并将其交换回来,使得树再次成为合法的二叉搜索树。

因为中序遍历能够产生一个升序排列的序列,所以我们可以通过中序遍历来检查这个序列是否有序。一旦发现不符合升序排列的部分,就可以确定是这两个节点的位置出了问题。

中序遍历中出现的错误情况分析

假设我们通过中序遍历得到了一个错误的序列。我们可以用以下思路来恢复树:

  1. 遍历中第一次发现逆序对时,可以确定较大的节点是第一个错误节点(i)。
  2. 遍历中第二次发现逆序对时,可以确定较小的节点是第二个错误节点(j)。

特别情况:有时两个错误节点可能是相邻的。在这种情况下,我们只会发现一次逆序对,这时第一个错误节点(i)是较大的节点,第二个错误节点(j)是较小的节点。

  1. 交换这两个节点的值,就可以恢复这棵树。
举个简单的例子:

假设有这样一棵二叉搜索树:

    3
   / \
  1   4
     /
    2

正常情况下,按照中序遍历,应该得到序列 [1, 2, 3, 4],但由于节点值 23 被错误地交换了,实际得到的序列是 [1, 3, 2, 4]

步骤:

  • 首先,中序遍历到1,没有问题。
  • 接着,遍历到3,仍然没问题。
  • 当遍历到2时,发现3 > 2,这是第一个也是唯一的逆序对,确定3是第一个错误节点(i),2是第二个错误节点(j)。

此时,我们只需要交换32,恢复成正确的树结构:

    2
   / \
  1   4
     /
    3

中序遍历得到的序列为[1, 2, 3, 4],树恢复正常。

代码实现

下面是C++代码的实现:

class Solution {
public:
    TreeNode* pre = nullptr;
    TreeNode* i = nullptr;
    TreeNode* j = nullptr;
    void dfs(TreeNode* root) {
        if (!root) return;
        dfs(root->left);
        if (pre && pre->val > root->val) {
            if (!i) i = pre;
            j = root;
        }
        pre = root;
        dfs(root->right);
    }
    void recoverTree(TreeNode* root) {
        dfs(root);
        if (i && j) swap(i->val, j->val);
    }
};

总结

这道题的关键在于理解二叉搜索树的性质和中序遍历的特性,通过检测逆序对来找到被错误交换的两个节点,进而将其恢复。这种思路能够覆盖所有可能的错误节点排列情况,并且实现起来也相对简单,是解决这类问题的有效方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值