原题链接:从前序与中序遍历序列构造二叉树
个人解法
思路:
由前序遍历可以知道根,由根可以知道左右子树的中序遍历,那么我们可以递归,分别摘出左子树前序遍历数组和中序遍历数组,摘出右子树前序遍历数组和中序遍历数组。
时间复杂度: O ( n 2 ) O(n^2) O(n2)
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(!preorder.size()) return nullptr;
TreeNode *root = new TreeNode(preorder[0]);
int p = 1, i = 0;
vector<int> l_pre, r_pre;
vector<int> l_in, r_in;
while(inorder[i] != root->val) {
l_pre.push_back(preorder[p]);
l_in.push_back(inorder[i]);
p ++, i ++;
}
i ++;
while(i < inorder.size()) {
r_pre.push_back(preorder[p]);
r_in.push_back(inorder[i]);
p ++, i ++;
}
root->left = buildTree(l_pre, l_in);
root->right = buildTree(r_pre, r_in);
return root;
}
};
更好的解法
思路:
我们可以利用前序遍历的下标与中序遍历中值相等的下标做一个映射关系,这样我们就可以省去递归中找根的 O ( n ) O(n) O(n)操作,优化为 O ( 1 ) O(1) O(1)
时间复杂度: O ( n ) O(n) O(n)
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
unordered_map<int, int> index;
TreeNode *build(vector<int> &pre, vector<int> &in, int pre_left, int pre_right, int in_left, int in_right) {
if(pre_left > pre_right) return nullptr;
int pre_root = pre_left;
int in_root = index[pre[pre_root]];
TreeNode *node = new TreeNode(pre[pre_root]);
int left_cnt = in_root - in_left;
node->left = build(pre, in, pre_left + 1, pre_left + left_cnt, in_left, in_root - 1);
node->right = build(pre, in, pre_left + left_cnt + 1, pre_right, in_root + 1, in_right);
return node;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i = 0;i < preorder.size();i ++)
index[inorder[i]] = i;
return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
}
};