Leetcode 99

二叉搜索树中的两个节点被错误地交换。

请在不改变其结构的情况下,恢复这棵树。

 

给题解二的代码做个笔记。

class Solution {
public:
    void recoverTree(TreeNode* root) {
        stack<TreeNode*> stk;
        TreeNode* x = nullptr;
        TreeNode* y = nullptr;
        TreeNode* pred = nullptr;

        while (!stk.empty() || root != nullptr) {
            while (root != nullptr) { // 这里是中序遍历的访问到左子树最左节点的部分
                stk.push(root);
                root = root->left;
            }
            root = stk.top(); // 遍历根节点的部分
            stk.pop();
            if (pred != nullptr && root->val < pred->val) { // 判断是否存在逆序的部分
                y = root;
                if (x == nullptr) {
                    x = pred;
                }
                else break; // 注意这个else,正解是第二个逆序的节点
            }
            pred = root;
            root = root->right; // 遍历右子树部分
        }

        swap(x->val, y->val);
    }
};

 

这里的 else break 很精髓。因为调换如果不是发生在相邻两个节点之间,那么就会产生两个逆序。

比如 [1,3,2,4],你发现 3 之后的 2 是逆序,但 4 不是,此时遍历已经完了,那么你就可以确定 3 和 2 需要交换。

那么对于 [7,3,5,1],你发现 7-3 是逆序,还不能直接调换。当你发现第二个逆序 5-1 的时候,才确定是 7 和 1 之间调换。

posted on 2020-08-08 23:31  Ricochet!  阅读(138)  评论(0编辑  收藏  举报