• 数据结构之美--树(01)


    1.重建二叉树

    题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回

    思路:前序(根左右)遍历的第一个节点就是根节点,于是我们在中序(左根右)遍历中找到该节点,于是该节点就把树划分成了左子树和右子树,之后递归求解即可

    /**
     * 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:
    	TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder)
    	{
    		auto pre_size = preorder.size();
    		auto in_size = inorder.size();
    
    		if (pre_size != in_size || pre_size == 0 || in_size == 0)
    			return nullptr;
    
    		return fun(preorder, 0, pre_size - 1, inorder, 0, in_size - 1);
    	}
    	TreeNode *fun(vector<int> &preorder, int preL, int preR, 
    		vector<int> &inorder, int inderL, int inderR)
    	{
    		if (preL > preR)
    			return nullptr;
    		TreeNode *root = new TreeNode(preorder[preL]);
    
    		int i = 0;
    		for (; i <= inderR; i++)
    		{
    			if (inorder[i] == preorder[preL])
    				break;
    		}
    
    		int left_size = i - inderL;
    		int right_size = inderR - i;
    
    		root->left = fun(preorder, preL + 1, preL + left_size, 
    			inorder, inderL, i - 1);
    
    		root->right = fun(preorder, preL + left_size + 1, preR, 
    			inorder, i + 1, inderR);
    
    		return root;
    	}
    };
    

    4. 序列化二叉树

    题目:实现两个函数,分别用来序列化和反序列化二叉树
    题解:首先,前序遍历化为一个序列! 
    反序列化时,第一个就是root,之后前半部分是左子树,后半部分是右子树,遇到一个’#'就得回到前面去找其

    class Codec
    {
      public:
        // Encodes a tree to a single string.
        string serialize(TreeNode *root)
        {
            if (root == nullptr)
                return "#";
            return to_string(root->val) + "," + serialize(root->left) +","+ serialize(root->right);
        };
        // Decodes your encoded data to tree.
        TreeNode *deserialize(string data)
        {
            return fun(data);
        }
    
      private:
        TreeNode *fun(string &data)
        {
            if (data == "")
                return nullptr;
            if (data[0] == '#')
            {
                data = data.substr(data.find(',')+1);
                return nullptr;
            }
    
            size_t idx=0;
            int x = stoi(data,&idx);
             data = data.substr(idx + 1);
            
            TreeNode *root = new TreeNode(x);
            
            root->left = fun(data);
            root->right = fun(data);
            return root;
        }
    };
    

    这是最骚的:

    class Codec {
        private:
        TreeNode* _root;
    public:
    
        // Encodes a tree to a single string.
        string serialize(TreeNode* root) {
            _root = root;
            return string();
        }
        // Decodes your encoded data to tree.
        TreeNode* deserialize(string data) {
            return _root;
        }
    };
    

    3. BST的后序遍历序列

    题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同

    后序遍历(左右根).最后一个节点一定是整个树的根节点,根据树与递归的关系,泛化而讲,他会是的根节点(包括左子树,右子树等等).所以我们的思路就是先找到根,然后判断前部分(相当于左子树)是否小于根,后部分(相当于右子树)是否大于根即可

    class Solution
    {
      public:
        bool VerifySquenceOfBST(vector<int> sequence)
        {
            int sz = sequence.size();
            if (sz == 0)
                return false;
            return IsBST(sequence, 0, sz - 1);
        }
        //第一部分是左子树结点的值,它们都比根结点的值小
        bool IsBST(const vector<int> &sequence, int left, int right)
        {
            if (left >= right)
                return true;
            int mid, tp = left;
            int root = sequence.at(right);
            /*先找左子树*/
            while (tp < right && sequence.at(tp) < root)
            {
                tp++;
            }
            if (tp < right)
            {
                mid = tp;
                //第二部分是右子树结点的值,它们都比根结点的值大
                // 查找右子树是否符合要求
                while (tp < right)
                {
                    if (sequence.at(tp) < root)
                    {
                        return false;
                    }
                    tp++;
                }
            }
            // 递归的判断左右子树是否符合要求
            return IsBST(sequence, left, mid - 1) && IsBST(sequence, mid, right - 1);
        }
    };
    

  • 相关阅读:
    【JavaWeb】Hibernate Dao层设计
    【C#】身份证识别(一):身份证号定位
    【JavaWeb】SpringMVC重定向页面取值
    关于chrome扩展的东西
    【C#】基于Opencv/Emgucv的身份证识别
    Bashware
    【java多线程】分段阶乘计算
    【java】多项式计算(中缀转后缀)
    iOS  OTA问题排查【itms-servers协议在线安装ipa包】
    【深度学习】BP算法分类iris数据集
  • 原文地址:https://www.cnblogs.com/Tattoo-Welkin/p/10335238.html
Copyright © 2020-2023  润新知