面试题7:重建二叉树原题链接
方法1:使用vector存储左右子树的前序、中序遍历结果然后直接递归调用建树函数。
/**
* 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) {
/* 思路:由前序遍历的第一个元素得到当前树的根,然后在将中序遍历中的根左右的值切分为左右子树。
时间复杂度 O(n^2)
空间复杂度 O(n^2)
*/
if(preorder.size() == 0)
return NULL;
int root_val = preorder[0], right = 0;
vector<int> lefti,righti, leftp, rightp;
for(int i = 0;i < inorder.size(); i++){
if(inorder[i] == root_val){
right = 1;
continue;
}
if(right == 0)
lefti.push_back(inorder[i]);
else
righti.push_back(inorder[i]);
}
for(int i = 1;i < preorder.size(); i++){
if(leftp.size() < lefti.size())
leftp.push_back(preorder[i]);
else
rightp.push_back(preorder[i]);
}
TreeNode* root = new TreeNode(root_val);
root->left = this->buildTree(leftp, lefti);
root->right = this->buildTree(rightp, righti);
return root;
}
};
方法2:直接在原数组中通过开始下标和结束下标指出子树的遍历结果,降低空间复杂度。
/**
* 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) {
/* 思路:由前序遍历的第一个元素得到当前树的根,然后在将中序遍历中的根左右的值切分为左右子树。
时间复杂度 O(n^2)
空间复杂度 O(1)
*/
return helper(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
TreeNode* helper(vector<int>& preorder, int pb, int pe, vector<int>& inorder, int ib, int ie){
// preorder [pb, pe) inorder [ib, ie)
if(pb >= pe)
return NULL;
int root_val = preorder[pb];
int left_pb, left_pe, left_ib, left_ie;
int right_pb, right_pe, right_ib, right_ie;
left_ib = ib;
for(int i = ib;i < ie; i++){
if(inorder[i] == root_val){
left_ie = i;
break;
}
}
right_ib = left_ie+1;
right_ie = ie;
int left_tree_node_num = left_ie - left_ib;
left_pb = pb+1;
left_pe = pb+1+left_tree_node_num;
right_pb = left_pe;
right_pe = pe;
TreeNode* root = new TreeNode(root_val);
root->left = helper(preorder, left_pb, left_pe, inorder, left_ib, left_ie);
root->right = helper(preorder, right_pb, right_pe, inorder, right_ib, right_ie);
return root;
}
};