• Recover Binary Search Tree


    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?

    confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.


    OJ's Binary Tree Serialization:

    The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

    Here's an example:

       1
      / 
     2   3
        /
       4
        
         5
    
    The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".
     
    这道题是要求恢复一颗有两个元素调换错了的二叉查找树。一开始拿到可能会觉得比较复杂,其实观察出规律了就比较简单。主要还是利用二叉查找树的主要性质,就是中序遍历是有序的性质。那么如果其中有元素被调换了,意味着中序遍历中必然出现违背有序的情况。那么会出现几次呢?有两种情况,如果是中序遍历相邻的两个元素被调换了,很容易想到就只需会出现一次违反情况,只需要把这个两个节点记录下来最后调换值就可以;如果是不相邻的两个元素被调换了,举个例子很容易可以发现,会发生两次逆序的情况,那么这时候需要调换的元素应该是第一次逆序前面的元素,和第二次逆序后面的元素。比如1234567,1和5调换了,会得到5234167,逆序发生在52和41,我们需要把4和1调过来,那么就是52的第一个元素,41的第二个元素调换即可。
    搞清楚了规律就容易实现了,中序遍历寻找逆序情况,调换的第一个元素,永远是第一个逆序的第一个元素,而调换的第二个元素如果只有一次逆序,则是那一次的后一个,如果有两次逆序则是第二次的后一个。算法只需要一次中序遍历,所以时间复杂度是O(n),空间是栈大小O(logn)。
    C++代码如下: 
    #include<iostream>
    #include<new>
    using namespace std;
    
    
    //Definition for binary tree
    struct TreeNode
    {
        int val;
        TreeNode *left;
        TreeNode *right;
        TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    };
    
    class Solution
    {
    public:
        TreeNode *first=NULL;
        TreeNode *second=NULL;
        TreeNode *pre=NULL;
        void recoverTree(TreeNode *root)
        {
            recoverInorder(root);
            swap(first->val,second->val);
        }
        void recoverInorder(TreeNode *root)
        {
            if(root)
            {
                recoverInorder(root->left);
                if(pre&&pre->val>root->val)
                {
                    if(first==NULL)
                    {
                        first=pre;
                        second=root;
                    }
                    else
                        second=root;
                }
                pre=root;
                recoverInorder(root->right);
            }
        }
        void createTree(TreeNode *&root)
        {
            int arr[10]= {5,9,7,8,6,10,4,2,1,3};
            int i;
            for(i=0; i<10; i++)
                insert(root,arr[i]);
        }
        void insert(TreeNode *&root,int key)
        {
            TreeNode *tmp=new TreeNode(key);
            if(root==NULL)
            {
                root=tmp;
            }
            else if(key<root->val)
                insert(root->left,key);
            else
                insert(root->right,key);
        }
        void inorder(TreeNode *root)
        {
            if(root)
            {
                inorder(root->left);
                cout<<root->val<<" ";
                inorder(root->right);
            }
        }
    };
    
    int main()
    {
        Solution s;
        TreeNode *root=NULL;
        s.createTree(root);
        s.inorder(root);
        cout<<endl;
        swap(root->left->val,root->right->val);
        s.inorder(root);
        cout<<endl;
        s.recoverTree(root);
        s.inorder(root);
    }

    运行结果:

  • 相关阅读:
    RTThread | 启动下一代RTOS演化
    开发者应该开始学习C++吗?
    用googleperftool分析程序的内存/CPU使用
    看书看累了,可以换看技术视频也是一种学习的方式
    分享:nginx virtuanenv django1.4 应用简单部署
    分享:不同编程语言之间转换的项目矩阵
    【EDUPEPN8508GS黄金版】EDUP EPN8508GS黄金版 迷你USB无线网卡【行情 报价 价格 评测】
    分享:20 本优秀的 Python 电子书
    说说设计模式~工厂方法模式(Factory Method)
    说说设计模式~简单工厂模式(Factory)
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4122686.html
Copyright © 2020-2023  润新知