重建二叉树
要求:时间限制: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在中序遍历中的位置下标,以该位置将中序遍历分为左树与右树,然后递归,示意图如下:
![](https://img2020.cnblogs.com/i-beta/1059417/202003/1059417-20200304212846564-495652198.png)
/** * 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的开始下标,以及结束下标的计算