99. Recover Binary Search Tree

问题描述:

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Example 1:

Input: [1,3,null,null,2]

   1
  /
 3
  \
   2

Output: [3,1,null,null,2]

   3
  /
 1
  \
   2

Example 2:

Input: [3,1,4,null,null,2]

  3
 / \
1   4
   /
  2

Output: [2,1,4,null,null,3]

  2
 / \
1   4
   /
  3

Follow up:

  • A solution using O(n) space is pretty straight forward.
  • Could you devise a constant space solution?

解题思路:

通过上一道题学习到的解题方法:利用中序遍历啊来判断二叉树是否为一颗二叉树。

这次我也利用了中序遍历。

观察给出的两个例子:

[3,1,4,null,null,2]

中序遍历为1-3-2-4,实际应为1-2-3-4

[1,3,null,null,2]

中序遍历为3-2-1,实际应为1-2-3

因为二叉树的性质:小于节点的在左,大于节点的在右

使用中序排序得到的序列应为一个递增序列。

因为是调换了两个节点,则必然是小的跑到了后面,大的跑到了前面

我们可以利用中序遍历查找第一个大于后面的值的节点,此为被调换的第一个节点

查找小于前一个值的节点,此为第二个节点。

需要注意的是:有两个节点排序中相邻,即给出的第二个例子的情况,所以再加一个指针记录可能的第二个节点。

一定要记住移动pre!!!(我就忘了。。小声bb

代码:

/**
 * 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) {
        bool change = false;
        stack<TreeNode*> stk;
        TreeNode* pre = NULL;
        TreeNode* cur = root;
        TreeNode* t1 = NULL;
        TreeNode* t2 = NULL;
        while(cur || !stk.empty()){
            while(cur){
                stk.push(cur);
                cur = cur->left;
            }
            cur = stk.top();
            stk.pop();
            if(!pre)
                pre = cur;
            else{
                if(cur->val < pre->val){
                    if(!t1){
                        t1 = pre;
                        t2 = cur;
                    }
                    else{
                       int temp = cur->val;
                        cur->val = t1->val;
                        t1->val = temp;
                        change = true;
                        break; 
                    }
                }
            }
            pre = cur;
            cur = cur->right;
        }
        if(!change){
            int temp = t1->val;
            t1->val = t2->val;
            t2->val = temp;
        }
    }
};

看看另一种48ms解法 空间复杂度为O(n),我的为76ms:

× Close
sample 48 ms submission
/**
 * 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* first = NULL,*second = NULL,*parent = NULL;
        TreeNode* cur,*pre;
        cur = root;
        while(cur)
        {
            if(!cur->left)
            {
                if(parent && parent->val > cur->val)
                {
                    if(!first)
                        first = parent;
                    second = cur;
                }
                parent = cur;
                cur = cur->right;
            }
            else
            {
                pre = cur->left;
                while(pre->right && pre->right != cur)
                    pre = pre->right;
                if(!pre->right)
                {
                    pre->right = cur;
                    cur = cur->left;
                }
                else
                {
                    pre->right = NULL;
                    if(parent->val > cur->val)
                    {
                        if(!first)
                            first = parent;
                        second = cur;
                    }
                    parent = cur;
                    cur = cur->right;
                }
            }
        }
        if(first && second) swap(first->val,second->val);
    }
};

猜你喜欢

转载自www.cnblogs.com/yaoyudadudu/p/9153884.html