99. Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note: A solution using O(n) space is pretty straight forward. Could
you devise a constant space solution?

这一题问题很简单,找出错误交换的两个元素,对于BST, 其实这就是个遍历的问题,因为二叉查找树中序下的严格升序性质可以很好的解决这类问题,这题之所以是hard就是因为看你是否能用常量空间解决,如同他说得一样。如果可以使用个O(n)大小的空间的话,那么直接遍历输出数据到数组或者栈,检查不满足升序的两处即可。这里得注意,交换后会出现的两种可能,如果是相邻两项交换,那么只有一处不满足升序,如果不是,那么有两处,这里需要分类判断下,锁定不同情况下的错误位置。

方法一:使用额外空间输出信息
void recoverTree(TreeNode* root) {
    vector<TreeNode*> res;
    helper(root, res);
    TreeNode* first;
    TreeNode* second;
    int i;
    bool once = false;
    for (i = 0; i < res.size() - 1; i++) {
        if (res[i]->val > res[i+1]->val && once == false) {
            first = res[i];
            second = res[i+1];
            once = true; //如果是一处,那么直接这俩交换
        }
        else {// 如果是两处错误,那么应该是第一处的第一个和第二处的第二个交换
            if (res[i]->val > res[i+1]->val) 
            second = res[i+1];
        }
    }
    int temp;
    temp = first->val;
    first->val = second->val;
    second->val = temp;

}
// 简单的递归将数据输出到数组
void helper(TreeNode* t, vector<TreeNode*>& res) {
    if (t != NULL) {
        helper(t->left, res);
        res.push_back(t);
        helper(t->right, res);
    }
}
方法二:morris traversal

其实二叉树遍历来做这道题的话,还得是常量空间,首先想到的就是morris traversal,所以这里其实只要稍微改动就行,可以用一个lastnode来记录上一个节点,然后跟当前节点比较,如果不满足升序记录下节点即可。主要还是在morris算法本身。

void recoverTree(TreeNode* root) {
    TreeNode *cur = root, *prev = NULL, *last = NULL;
    TreeNode *first, *second;
    bool once = false;
    while (cur != NULL) {
        if (last != NULL && last->val > cur->val) {
            if (once == false) {
                first = last;
                second = cur;
                once = true;
            }
            else second = cur;
        }
        if (cur->left == NULL) {
            last = cur;
            cur = cur->right;
        }
        else {
            prev = cur->left;
            while (prev->right != NULL && prev->right != cur)
                prev = prev->right;

            if (prev->right == NULL) {
                prev->right = cur;
                cur = cur->left;
            }
            else {
                prev->right = NULL;
                last = cur;
                cur = cur->right;
            }
        }
    }
    int temp = first->val;
    first->val = second->val;
    second->val = temp;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值