LeetCode-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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
同时也是剑指offer的面试题7。

思想

任务本质就是根据先序和中序序列构造二叉树,那么可以用递归的思想。

buildTree(先序序列,中序序列){  
   找到根结点root;  
   找到左子树的先序序列和中序序列;  
   找到右子树的先序序列和中序序列;   
   root->left=buildTree(左子树的先序序列,左子树的中序序列);    
   root->right=buildTree(右子树的先序序列,右子树的中序序列);   
}

代码

/**
 * 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) {
        if(preorder.empty()||inorder.empty())
            return NULL;
        int presize=preorder.size();
        int insize=inorder.size();
        TreeNode * root = new TreeNode(preorder[0]);   //先序遍历的第一个肯定是根结点
        root->left=root->right=NULL;
        if(presize==1)  //递归序列只剩一个的时候,那这个肯定是叶子结点,同时也是根节点,这也是递归结束标志
            if(insize==1)
                return root;
            else
                return NULL;
        int rootVal=preorder[0];
        int inPoint;
        for(int i=0;i<insize;++i)    //扫描中序遍历的序列,找到根结点对应的位置inPoint
        {
            if(inorder[i]==rootVal)
            {
                inPoint=i;   // inPoint的左边是左子树,右边都是右子树
                break;
            }
        }
        if(inorder[inPoint]!=rootVal)
            return NULL;
        int leftLength=inPoint;  //计算左子树序列长度
        int rightLength=insize-inPoint-1;   //右子树序列长度
        vector<int> newLeftPreorder;   //生成新的左子树先序序列
        vector<int> newRightPreorder;  //生成新的右子树先序序列
        for(int i=1;i<=leftLength;++i)   //第0个是root节点,1到leftLength是左子树
        {
            newLeftPreorder.push_back(preorder[i]);
        }
        for(int i=1+leftLength;i<presize;++i)  //leftLength+1到序列尾部都是右子树
        {
            newRightPreorder.push_back(preorder[i]);
        }
        vector<int> newLeftinorder; //生成新的左子树中序序列
        vector<int> newRightinorder;  //生成新的右子树中序序列
        for(int i=0;i<leftLength;++i)  //0到leftLength左子树
        {
            newLeftinorder.push_back(inorder[i]);
        }
        for(int i=inPoint+1;i<insize;++i)  //inPoint是root,inPoint+1到尾部是右子树
        {
            newRightinorder.push_back(inorder[i]);
        }
        root->left=buildTree(newLeftPreorder,newLeftinorder); //递归构造左子树
        root->right=buildTree(newRightPreorder,newRightinorder);  //递归构造右子树
        
        return root;
        
        
    }
};
posted @ 2019-09-18 17:41  HaoPeng_Zhang  阅读(57)  评论(0编辑  收藏