LeetCode —— 99. 恢复二叉搜索树

文章目录

  • 题目描述
  • 示例
    • 示例一
    • 示例二
  • 解题思路
  • 代码
  • 参考文献

题目描述

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

示例

示例一

LeetCode —— 99. 恢复二叉搜索树_第1张图片
输入:root = [1,3,null,null,2]
输出:[3,1,null,null,2]
解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。

示例二

LeetCode —— 99. 恢复二叉搜索树_第2张图片
输入:root = [3,1,4,null,null,2]
输出:[2,1,4,null,null,3]
解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。

解题思路

首先我们要明白BST的特性之一就是其中序遍历的结果是顺序的!那么我们就可以利用中序遍历的思想了。

首先我们需要一个变量prev_node其指向当前节点的上一个节点,当然其一开始是指向root节点的。之后我们遍历这个二叉树。如果我们发现当前节点的元素是小于上一个节点的,那么说明我们定位到了错误的节点!用两个指针保存当前节点和前一个节点的地址。

之后,我们遍历完,用刚刚的两个指针把这两个节点的val值交换就可以。

代码

class Solution {
 public:
  TreeNode* prev_node = nullptr;  //保存前一个节点
  TreeNode* pre_node = nullptr;  //当找到错误节点时,定位前一个节点的地址
  TreeNode* cur_node = nullptr;  //当找到错误节点时,定位当前节点的地址

  /**
   * @brief 遍历节点,定位到错误节点
   *
   * @param node 当前节点的地址
   */
  void traverse(TreeNode* node) {
    if (node == nullptr) return;

    traverse(node->left);

    //找到错误节点
    if (prev_node != nullptr && prev_node->val > node->val) {
      if (pre_node == nullptr) pre_node = prev_node;
      cur_node = node;
    }
    prev_node = node;

    traverse(node->right);
  }

  /**
   * @brief leetcode 提供的函数
   *
   * @param root 根节点
   */
  void recoverTree(TreeNode* root) {
    if (root == nullptr) return;
    traverse(root);
    swap(pre_node->val, cur_node->val);
  }
};

参考文献

[1] labuladong的算法小抄[M].付东来

你可能感兴趣的:(算法,leetcode,算法,深度优先)