(leetcode 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?

如果使用额外空间,即中序遍历,然后将中序便利结果排序(也可以不排序,直接找,从左到右找最左侧不符合顺序的为n1,从右到左找不符合顺序的为n2),最后将排序好的结果再填进去

class Solution {
public:
    void recoverTree(TreeNode* root) {
        //Inorder
        vector<int> v;
        TreeNode *pCur = root;
        stack<TreeNode*> s;
        while (!s.empty() || pCur) {
            while (pCur) {
                s.push(pCur);
                pCur = pCur->left;
            }
            if(!s.empty()){
                v.push_back(s.top()->val);
                pCur = s.top()->right;
                s.pop();
            }
        }
        
        sort(v.begin(),v.end());
        int idx = 0;
      
        pCur = root;
        stack<TreeNode*> s1;
        
        while (!s1.empty() || pCur) {
            while (pCur) {
                s1.push(pCur);
                pCur = pCur->left;
            }
            if(!s1.empty()){
                s1.top()->val = v[idx++];
                pCur = s1.top()->right;
                s1.pop();
            }
        }   
    }
};


其实如果写完上面程序,其实可以发现,没必要使用vector额外空间,中序遍历过程中就可以找到n1和n2

class Solution {
public:
    void recoverTree(TreeNode* root) {
        TreeNode *pCur = root;
        stack<TreeNode*> s;
        TreeNode *pre1 = NULL;
        TreeNode *leftToSwap = NULL;
        TreeNode *rightToSwap = NULL;
        int cntUnorder = 0;
        while (!s.empty() || pCur) {
            while (pCur) {
                s.push(pCur);
                pCur = pCur->left;
            }
            if(!s.empty()){
                //search from left to find the non-order node
                if(!pre1)
                    pre1 = s.top();
                else{
                    if(s.top()->val < pre1->val){
                        cntUnorder ++;
                        if(!leftToSwap)  leftToSwap = pre1;
                        rightToSwap = s.top();
                        if(cntUnorder>=2)
                            break;
                    }
                    pre1 = s.top();
                }
                //                
                pCur = s.top()->right;
                s.pop();
            }
        }
        int temp = leftToSwap->val;
        leftToSwap->val = rightToSwap->val;
        rightToSwap->val = temp;        
    }
};


即便如此,还是使用了O(n)的额外空间,中序遍历如何不使用额外空间呢,那只能递归了,同时一些关键变量就需要作为成员变量而不是局部变量

class Solution {
public:
    TreeNode *pre1;
    TreeNode *leftToSwap;
    TreeNode *rightToSwap;
    
    void recoverTree(TreeNode* root) {
        pre1 = leftToSwap = rightToSwap = NULL;
        
        inOrder(root);
        
        int temp = leftToSwap->val;
        leftToSwap->val = rightToSwap->val;
        rightToSwap->val = temp;
    }
    
    void inOrder(TreeNode *root)
    {
        if(root == NULL) return;
        inOrder(root->left);
        
        if(!pre1)
            pre1 = root;
        else{
            if(root->val < pre1->val){
                if(!leftToSwap)  leftToSwap = pre1;
                rightToSwap = root;
            }
            pre1 = root;
        }
        
        inOrder(root->right);
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值