【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 ;
    }
};
 
 

猜你喜欢

转载自www.cnblogs.com/wikiwen/p/10225835.html
今日推荐