Leetcode Recover Binary Search Tree

Leetcode Recover Binary Search Tree,本题的关键是“如何使用O(1)的空间遍历树”和“找出两个被swap的节点”。

如何使用O(1)的空间遍历树

这里主要需要使用一个数据节构Threaded binary tree,借助于Threaded binary tree可以很快的实现遍历。此外,使用in-order遍历搜索二叉树,正好是以升序遍历整个数据。

找出两个被swap的节点

由上一部分可知,我们以升序的方式遍历数据,如果有两个节点被交换,那么可以很简单的找到,第一个遇到的被交换的结点一定是较大的一个,所以通过相关判断可以很快的找出两个被交换的节点。

相关代码如下:

#include <iostream>
#include <algorithm>

using namespace std;

/**
 * We use the Threaded binary tree to solve this problem.
 * Threaded binary tree can scan the binary tree in O(1) space.
 * We using Threaded binary tree trave the origin binary search tree with
 * in-order, so we trave the tree in a increase sequence.
 * There are two element are swaped, so in this order, the first one encounted
 * of the two is the lagger one, and the other one is the smaller. We can
 * get the two by detect the trend of the element
 */

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
    void recoverTree(TreeNode* root) {
        if (!root) {
            return;
        }
        TreeNode* cur = root;
        TreeNode* cur_pre {};   // Record the element preceded current element
        TreeNode* pre;
        TreeNode* first {}; // The bigger swapped node
        TreeNode* second {};    // The smaller swapped node
        while (cur) {
            if (!cur->left) {
                /**
                 * There is not node less than this one
                 */
                // If not find the bigger one, we first search it
                if (!first && cur_pre && cur_pre->val > cur->val) {
                    first = cur_pre;
                }
                // If the bigger is found, we get the smaller
                if (first && cur_pre && cur_pre->val > cur->val) {
                    second = cur;
                }
                cur_pre = cur;
                cur = cur->right;
            } else {
                /**
                 * First scan the node which less than current
                 */
                pre = cur->left;
                while (pre->right && pre->right != cur) {
                    pre = pre->right;
                }
                if (!pre->right) {
                    // joint the sequence
                    pre->right = cur;
                    cur = cur->left;
                } else {
                    // disjoint the sequence and check the value
                    pre->right = nullptr;
                    if (!first && cur_pre && cur_pre->val > cur->val) {
                        first = cur_pre;
                    }
                    if (first && cur_pre && cur_pre->val > cur->val) {
                        second = cur;
                    }
                    cur_pre = cur;
                    cur = cur->right;
                }
            }
        }
        if (first && second) {
            swap(first->val, second->val);
        }
    }
    bool judge(TreeNode* cur, TreeNode* cur_pre) {
        if (cur->right && cur->val > cur->right->val) {
            return true;
        }
        if (cur_pre && cur_pre->val > cur->val) {
            return true;
        }
        return false;
    }
};

int main(/*int argc, char* argv[]*/) {
    Solution so;
    TreeNode* a = new TreeNode(2);
    a->right = new TreeNode(3);
    a->right->left = new TreeNode(1);
    so.recoverTree(a);
    cout << a->val << endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值