1. 题目

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?

2. 思路

二叉排序树是中序遍历严格有序递增的,采用中序遍历过程,比较整个序列中,当前节点和前一个节点的大小关系。第一后节点大于前节点的是前面一个被交换的节点。
第二个节点是前面一个被交换过的,所以如果某个节点比前一个节点小,就是第二个被交换过的。
如果没有找到第二个,交换的是相邻的两个,直接把第一次找到的pre和自身进行交换即可。

这里用了栈来做遍历,空间复杂度是O(logN)。 不符合题目的需求。

3. 代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void recoverTree(TreeNode* root) {
        TreeNode f(0);  // 找到的两个逆序点
        find(root, &f);
        int tmp = f.left->val;
        f.left->val = f.right->val;
        f.right->val = tmp;
    }
    
    void find(TreeNode* root, TreeNode* n) {
        TreeNode* s[256];  // 遍历栈
        int top = 0; 
        s[top] = root;
        TreeNode* pre = NULL;
        int cnt = 0; // find node num
        while (top >= 0) {
            if (s[top]->left != NULL) {
                s[top+1] = s[top]->left;
                top++;
                continue;
            }
            while (top >= 0) {
                if (cnt == 0) {
                    if (pre != NULL && s[top]->val < pre->val) {
                        n->left = pre;
                        n->right = s[top];
                        cnt++;
                    }
                } else {
                    if (pre != NULL && s[top]->val < pre->val) {
                        n->right = s[top];
                        return ;
                    }
                }
                pre = s[top];
                if (s[top]->right != NULL) {
                    s[top] = s[top]->right;
                    break;
                } else {
                    top--;
                }
            }
        }
    }
};

knzeus
72 声望28 粉丝

行万里路,读万卷书