• 【LeetCode & 剑指offer刷题】树题12:7 重建二叉树(系列)


    【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

    105. Construct Binary Tree from Preorder and Inorder Traversal

    Given preorder and inorder traversal of a tree, construct the binary tree.
    Note:
    You may assume that duplicates do not exist in the tree.
    For example, given
    preorder = [3,9,20,15,7]
    inorder = [9,3,15,20,7]
    Return the following binary tree:
    3
    /
    9 20
        /
        15 7
     
    /**
     * 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)
        {
            return buildOneLevel(preorder, 0, preorder.size()-1,inorder, 0 ,inorder.size()-1);
        }
       
        //递归函数功能:构建树的某一层结构
        TreeNode* buildOneLevel(vector<int>& preorder, int pre_begin, int pre_end, vector<int>& inorder, int in_begin, int in_end)//这里用下标法,需要6个形参,也可以用迭代器只需4个形参
        {
           
            if(pre_begin>pre_end || in_begin>in_end) return NULL; //递归子函数的出口
           
            //先找根节点(用前序遍历序列)
            TreeNode* root = new TreeNode(preorder[pre_begin]);
           
            //在找左子树和右子树(用中序遍历序列)
            int left_length = 0; //左子树长度
            for(int i = in_begin; i<= in_end; i++)
            {
                if(inorder[i] == root->val)
                {
                    left_length = i;
                    break; //先找到中序遍历序列中根节点的位置
                }
            }
            left_length -= in_begin; //左子树长度
           
            root->left = buildOneLevel(preorder, pre_begin+1, pre_begin+left_length, inorder, in_begin, in_begin+left_length-1);//左子树
            root->right = buildOneLevel(preorder, pre_begin+left_length+1, pre_end, inorder,in_begin+left_length+1,in_end); //右子树
           
            return root; //递归母函数的出口
                   
        }
    };*/
    #include <algorithm>
    class Solution
    {
    public:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
        {
            return buildOneLevel(preorder.begin(), preorder.end(), inorder.begin(), inorder.end()); //!!注意end指向容器末尾(最后一个元素的下一个位置)
        }
       
        //递归函数功能:构建树的某一层结构
     //   template<typename iterator> //也可直接用vector<int>::iterator类型,模板可以进行类型延伸(泛型编程),避免不同类型写多个函数(自己的思考),但函数内部的很多变量名需用auto
        using iter = vector<int>::iterator;//为便于书写,也可使用类型别名 (同typedef)
        TreeNode* buildOneLevel(iter pre_begin, iter pre_end, iter in_begin, iter in_end)
        {
           
            if(pre_begin == pre_end || in_begin == in_end) return nullptr; //递归出口一(除结尾外还需要一个内部return,即两个return吧)
           
            //找根节点用前序遍历序列)
            TreeNode* root = new TreeNode(*pre_begin); //前序遍历序列首元素即为根结点
           
            //在找左子树和右子树(用中序遍历序列) (具体只用求左子树序列长度就可以了)
            vector<int>::iterator in_root_pos = find(in_begin, in_end, root->val); //先找到中序遍历序列中根节点的位置 (由于序列中不含重复元素,故可以用此方法)
            int left_length = in_root_pos - in_begin; //左子树序列长度
           
            root->left = buildOneLevel(pre_begin+1, pre_begin+left_length+1, in_begin, in_root_pos);//左子树(对于顺序容器的迭代器可以直接加某个常数,其他容器迭代器需用distance、next等函数)
            root->right = buildOneLevel(pre_begin+left_length+1, pre_end, in_root_pos+1, in_end); //右子树
           
            // !!注意end指向容器末尾(最后一个元素的下一个位置)
           
            return root; //递归出口二
                   
        }
    };
     
    106. Construct Binary Tree from Inorder and Postorder Traversal
    Given inorder and postorder traversal of a tree, construct the binary tree.
    Note:
    You may assume that duplicates do not exist in the tree.
    For example, given
    inorder = [9,3,15,20,7]
    postorder = [9,15,7,20,3]
    Return the following binary tree:
    3
    /
    9 20
        /
        15 7
     
    /**
     * 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>& inorder, vector<int>& postorder)
        {
            return build(postorder.begin(), postorder.end(), inorder.begin(), inorder.end());
        }
    private:
        using iter = vector<int>::iterator; //类型别名
        TreeNode* build(iter post_begin, iter post_end, iter in_begin, iter in_end)
        {
            if(post_begin == post_end || in_begin == in_end) return nullptr;
           
            //先找根结点(后序遍历最一个元素)
            TreeNode* root = new TreeNode(*(post_end-1)); //注意容器的end迭代器指向最后一个元素的下一个位置,而非最后一个元素!!
           
           // cout<<root->val<<endl;
            //再找左右子树(通过中序遍历,找到左右子树的分割点,求出左子树的长度)
            vector<int>::iterator in_root_pos = find(in_begin, in_end, root->val); //同过迭代器将STL中容器与算法联系起来
            int left_length = in_root_pos - in_begin;
           
            //左子树
            root->left = build(post_begin, post_begin + left_length, in_begin, in_root_pos);
            //右子树
            root->right = build(post_begin + left_length, post_end - 1, in_root_pos + 1, in_end);
           
            return root;
        }
    };
     
     
  • 相关阅读:
    分布式与集群的区别是什么?
    Java NIO:IO与NIO的区别 JAVA BIO与NIO、AIO的区别
    localStorage使用总结 JS 详解 Cookie、 LocalStorage 与 SessionStorage
    tomcat+nginx+redis实现均衡负载、session共享 存储过程的优缺点 HTTP、TCP、IP协议常见面试题
    高并发下的Java数据结构(List、Set、Map)
    [剑指offer] 31. 整数中1出现的次数(从1到n整数中1出现的次数)
    [剑指offer] 30. 连续子数组的最大和
    [剑指offer] 29. 最小的K个数
    [剑指offer] 28. 数组中出现次数超过一半的数字
    [leetcode] 51. N-Queens (递归)
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10225835.html
Copyright © 2020-2023  润新知