LeetCode(99)Recover Binary Search Tree

这道题目要求在不改变二叉搜索树结构的情况下,恢复因错误交换而顺序颠倒的两个节点。解决方案包括两种方法:第一种是O(n)空间复杂度,通过中序遍历相邻元素进行检查;第二种是O(1)空间复杂度,通过改造递归的中序遍历来找到顺序颠倒的节点。
摘要由CSDN通过智能技术生成

题目如下:

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?


分析如下:

第一个做法,也是我目前想到的最好的做法,是O(n) 空间复杂度的做法。就是在中序遍历的基础上,每两个元素为一组,检查是否是顺序颠倒的。

case1 : 发生顺序颠倒的两个元素是相邻元素

case2 : 发生顺序颠倒的两个元素不是相邻元素


代码如下:

//400ms通过大集合,我很好奇,这时间居然没有超时么?
/**
 * Definition for binary tree
 * 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==NULL)
            return;
        stack<TreeNode*> node_stack;
        while(root!=NULL){
            node_stack.push(root);
            root=root->left;
        }
        TreeNode* cur=NULL;
        TreeNode* pre=NULL;
        TreeNode* res_a=NULL;
        TreeNode* res_b=NULL;
        while(!node_stack.empty()) {
            cur=node_stack.top();
            node_stack.pop();
            if(pre!=NULL&&cur->val<=pre->val&&res_a==NULL){
                res_a=pre;
                res_b=cur;
            }else if(pre!=NULL&&cur->val<=pre->val&&res_a!=NULL) {
                res_b=cur;
            }
            pre=cur;
            cur=cur->right;
            while(cur!=NULL){
                node_stack.push(cur);
                cur=cur->left;
            }
        }
        int tmp=res_a->val;
        res_a->val=res_b->val;
        res_b->val=tmp;
        return;
    }
};

第二个做法,相当聪明。做到了O(1)的空间复杂度。

分析一下,要找到顺序颠倒的点,必然要中序遍历,如果中序遍历,要么用栈,要么非递归。如果用栈,必然用O(N)的空间复杂度。如果非递归,至少还有改造的希望。
于是问题转化为,改造递归的中序遍历,使得它的空间复杂度为O(1)并且依然能够找到顺序颠倒的点。
代码如下,搬运自 Yu's Coding Garden

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *first;
    TreeNode *second;
    TreeNode *pre;
     
    void inOrder(TreeNode *root){
        if (root==NULL)
            return;
        inOrder(root->left);
        if (pre == NULL){pre = root;}
        else {
            if (pre->val > root->val){
                if (first==NULL) {first = pre;}
                second = root;
            }
            pre = root;
        }
        inOrder(root->right);
    }
    void recoverTree(TreeNode *root) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        pre = NULL;
        first = NULL;
        second= NULL;
        inOrder(root);
        int val;
        val = first->val;
        first->val=second->val;
        second->val=val;
        return;
    }
};


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值