重建二叉树

要求:时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32M,其他语言64M

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回
 
思路一:
根据先序遍历找到根节点D在中序遍历中的位置下标,以该位置将中序遍历分为左树与右树,然后递归,示意图如下:
重建二叉树代码如下:
/**
 * 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* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if (pre.empty() || vin.empty())
        return NULL;
 
    vector<int> pre_left, pre_right, vin_left, vin_right;
    int val = pre[0];
    TreeNode* root = new TreeNode(val);
    int pos;
 
    for (pos = 0; pos < vin.size(); ++pos)
    {
        if (vin[pos] == val)
            break;
    }
 
    for (int i = 0; i < vin.size(); ++i){
 
        if (i < pos){
            vin_left.push_back(vin[i]);
            pre_left.push_back(pre[i + 1]);
        }
        else if (i > pos)
        {
            vin_right.push_back(vin[i]);
            pre_right.push_back(pre[i]);
        }
    }
    root->left = reConstructBinaryTree(pre_left, vin_left);
    root->right = reConstructBinaryTree(pre_right, vin_right);
    return root;
    }
};

思路二:巧妙之处在于重写构造函数reConstructBinaryTree,因涉及到的数据项偏多,这些项作为参数传给构造函数

/**
 * 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* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        TreeNode *root = reConstructBinaryTree(pre,0,pre.size()-1,vin,0,vin.size()-1);
        return root;
    }
     TreeNode *reConstructBinaryTree(vector<int>pre,int startPre,int endPre,vector<int> vin, int startVin,int endVin)
     {
         if(startPre > endPre || startVin > endVin)
         {
             return NULL;
         }
         TreeNode *root = new TreeNode(pre[startPre]);
         for (int i = startVin ;i <= endVin;i++)
         {
             if(vin[i] == pre[startPre])
             {
                 root->left = reConstructBinaryTree(pre,startPre+1,startPre + i - startVin,vin,startVin,i-1);
                 root->right = reConstructBinaryTree(pre,i-startVin+startPre+1,endPre,vin,i+1,endVin);
                 break;
             }
         }
          return root;
     }
   
};

其中要注意,比如递归中,pre的开始下标,以及结束下标的计算