- Construct Binary Tree from Preorder and Inorder Traversal
中文English
Given preorder and inorder traversal of a tree, construct the binary tree.
Example
Example 1:
Input:[],[]
Output:{}
Explanation:
The binary tree is null
Example 2:
Input:[2,1,3],[1,2,3]
Output:{2,1,3}
Explanation:
The binary tree is as follows
2
/
1 3
Notice
You may assume that duplicates do not exist in the tree.
解法1:
代码如下:
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
*@param preorder : A list of integers that preorder traversal of a tree
*@param inorder : A list of integers that inorder traversal of a tree
*@return : Root of a tree
*/
TreeNode * buildTree(vector<int> &preorder, vector<int> &inorder) {
return helper(preorder.begin(), preorder.end(), inorder.begin(), inorder.end());
}
private:
TreeNode * helper(vector<int>::iterator preorderStart, vector<int>::iterator preorderEnd,
vector<int>::iterator inorderStart, vector<int>::iterator inorderEnd) {
if (inorderStart == inorderEnd) return NULL;
vector<int>::iterator inorderRootIter = find(inorderStart, inorderEnd, *preorderStart);
TreeNode * root = new TreeNode(*inorderRootIter);
root->left = helper(preorderStart + 1, preorderStart + 1 + (inorderRootIter - inorderStart), inorderStart, inorderRootIter);
root->right = helper(preorderStart + 1 + (inorderRootIter - inorderStart), preorderEnd, inorderRootIter + 1, inorderEnd);
return root;
}
};
二刷:
/**
* 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) {
int rootValue = preorder[0];
TreeNode *root = new TreeNode(rootValue);
int n = preorder.size();
if (n == 1) return root;
int inOrderRootIndex = 0;
for (int i = 0; i < inorder.size(); i++) {
if (inorder[i] == rootValue) {
inOrderRootIndex = i;
break;
}
}
int leftChildNum = inOrderRootIndex, rightChildNum = n - leftChildNum - 1;
if (leftChildNum > 0) {
vector<int> preorderLeft(preorder.begin() + 1, preorder.begin() + leftChildNum + 1);
vector<int> inorderLeft(inorder.begin(), inorder.begin() + leftChildNum);
root->left = buildTree(preorderLeft, inorderLeft);
}
if (rightChildNum > 0) {
vector<int> preorderRight(preorder.begin() + leftChildNum + 1, preorder.end());
vector<int> inorderRight(inorder.begin() + leftChildNum + 1, inorder.end());
root->right = buildTree(preorderRight, inorderRight);
}
return root;
}
};
三刷:可以先把inorder的num和index关系保存下来,这样就不用一个循环去找了。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param preorder: A list of integers that preorder traversal of a tree
* @param inorder: A list of integers that inorder traversal of a tree
* @return: Root of a tree
*/
TreeNode* buildTree(vector<int> &preorder, vector<int> &inorder) {
int n1 = preorder.size(), n2 = inorder.size();
if (n1 == 0 || n1 != n2) return NULL;
for (int i = 0; i < n2; i++) um[inorder[i]] = i;
return helper(preorder, 0, n1 - 1, inorder, 0, n2 - 1);
}
private:
unordered_map<int, int> um; //<num, inorder_index>
TreeNode *helper(vector<int> &preorder, int start1, int end1,
vector<int> &inorder, int start2, int end2) {
if (start1 > end1) return NULL;
TreeNode *root = new TreeNode(preorder[start1]);
// if (start1 == end1) return root; 这一行可以不要
int pos = um[preorder[start1]];
int leftSize = pos - start2;
//root->left = helper(preorder, start1 + 1, start1 + pos, inorder, start2, start2 + pos - 1); //start2和pos不要搞混了!
root->left = helper(preorder, start1 + 1, start1 + leftSize, inorder, start2, pos - 1); //这里要用leftSize, 不能直接用pos
root->right = helper(preorder, start1 + leftSize + 1, end1, inorder, pos + 1, end2);
return root;
}
};
本文介绍了一种算法,用于根据给定的先序和中序遍历序列构建二叉树。通过三种不同的实现方式,详细展示了如何定位根节点,划分左右子树,并递归构建完整的二叉树结构。
3488





