zoukankan      html  css  js  c++  java
  • 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);
        }
    };
  • 相关阅读:
    雨天的尾巴「线段树合并+树上差分」
    硬币购物「容斥+背包」
    消失之物「分治+背包」
    最小距离「多源最短路」
    任务分配「最短路+DP」
    LCA「树链剖分+线段树」
    组合计数基础
    SPOJ-QTREE4 Query on a tree IV
    K-D tree 区域查询复杂度证明
    bitset 求解高维偏序
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9153884.html
Copyright © 2011-2022 走看看