LeetCode | Recover Binary Search Tree(恢复二叉搜索树)

wo 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?

题目解析:

做题要看问题的对象。这个题目是二叉搜索树的两个结点交换了,带来的结果是,中序遍历得到的不是有序的。很简单的方法是,设置一个n的数组,然后中序遍历,最后交换两个不符合规则的结点。

题目中要求使用常量空间,那么我们从上面的中序遍历中怎么得到启发呢?先看中序遍历后如何找到两个不符合规则的结点。比如:1-2-7-4-5-6-3-8。显然3要和7进行交换。那么怎么找到7,怎么找到3?从前向后遍历,当当前值比前一个值小的时候,前一个值要和后面的交换,再往后遍历,当当前值比前一个数小的时候,说明找到了第二个结点。然后将找到的两个结点交换。

有两个需要注意的地方:

1、两次查找的时候,都是当前值比前一个小的时候,但第一次取前一个值,第二个取后一个值。

2、如果需要交换的两个点正好相邻呢?所有当big被赋值的时候,small也要被赋值!

class Solution {
public:
    void recoverTree(TreeNode *root) {
        if(root == NULL)
            return ;
        InOrderTraverse(root);
    }
    void InOrderTraverse(TreeNode *root){
        stack<TreeNode *> S;
        TreeNode *p = root;
        vector<int> num;
        TreeNode *tmp = NULL;
        TreeNode *big = NULL;
        TreeNode *small = NULL;
        bool flag = false;
        while(p || !S.empty()){
            if(p){
                S.push(p);
                p = p->left;
            }else{
                p = S.top();
                S.pop();
                if(tmp == NULL){
                    tmp = p;
                    p = p->right;
                    continue;
                }
                if(!flag){
                    if(tmp->val > p->val){
                        big = tmp;
                        small = p;
                        flag = true;
                    }
                }else{
                    if(tmp->val > p->val){
                        small = p;
                        break;
                    }
                }
                tmp = p;
                p = p->right;
            }
        }
        int a = big->val;
        big->val = small->val;
        small->val = a;
    }
};

点赞