LeetCode: 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?

思路:

对二叉搜索树进行中序遍历,可以得到排序好的数组。如果二叉树中,两个节点被swap,那么第一个节点的中序后继必然小于它,第二个节点必然小于它的中序前继。因此,对二叉树进行中序遍历,即可得到两个出错节点的指针。对二叉树中序遍历,可以采用递归方式,也可以采用迭代方式。我分别用这两种方式实现。但是无论使用迭代方式,还是递归方式,算法空间复杂度均为O(logn)。而题目要求空间复杂度为常数让人很迷惑。因为就算是使用递归方式遍历,其调用栈的空间复杂度也在O(logn)。 

代码:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    TreeNode* prev, *mistake1, *mistake2;
    
    void inOrder(TreeNode* root)
    {
        if(root == NULL)
            return;
        inOrder(root->left);
        if(prev != NULL && prev->val > root->val)
        {
            if(mistake1 == NULL)
            {
                mistake1 = prev;
                mistake2 = root;
            }
            else
                mistake2 = root;


        }
        prev = root;
        inOrder(root->right);
    }
    
    void inOrderIter(TreeNode* root)
    {
        if(root == NULL)
            return;
        stack<TreeNode *> s;
        TreeNode* p = root;
        while(!s.empty() || p)
        {
            if(p) 
            {
                s.push(p);
                p = p->left;
            }
            else
            {
                p = s.top();
                if(prev != NULL && prev->val > p->val)
                {
                    if(mistake1 == NULL)
                    {
                        mistake1 = prev;
                        mistake2 = p;
                    }
                    else
                        mistake2 = p;


                }
                prev = p;
                s.pop();
                p = p->right;
            }
        }
    }
    
public:
    void recoverTree(TreeNode *root) {
        prev = mistake1 = mistake2 = NULL;
       //inOrder(root);
        inOrderIter(root);
        if(mistake1 != NULL && mistake2 != NULL)
        {
            int temp = mistake1->val;
            mistake1->val = mistake2->val;
            mistake2->val = temp;
        }
    }
};
点赞