题目描述
Given two integer arrays preorder
and inorder
where preorder
is the preorder traversal of a binary tree and inorder
is the inorder traversal of the same tree, construct and return the binary tree.
Example 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] Output: [3,9,20,null,null,15,7]
Example 2:
Input: preorder = [-1], inorder = [-1] Output: [-1]
Constraints:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder
andinorder
consist of unique values.- Each value of
inorder
also appears inpreorder
. preorder
is guaranteed to be the preorder traversal of the tree.inorder
is guaranteed to be the inorder traversal of the tree.
解题思路
【C++】
/**
* 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) {}
* };
*/
1. 递归
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return R(preorder, 0, preorder.size(), inorder, 0, inorder.size());
}
TreeNode* R(vector<int>& a, int aBegin, int aEnd, vector<int>& b, int bBegin, int bEnd) {
if (aBegin >= aEnd || bBegin >= bEnd) {return nullptr;}
TreeNode* root = new TreeNode(a[aBegin]);
int pivot = bBegin;
while (pivot < bEnd && b[pivot] != a[aBegin]) {pivot++;}
root->left = R(a, aBegin+1, aBegin+1+pivot-bBegin, b, bBegin, pivot);
root->right = R(a, aBegin+1+pivot-bBegin, aEnd, b, pivot+1, bEnd);
return root;
}
};
用一下hash,节省一点搜索开销
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
TreeNode *root,*curr;
int n = preorder.size();
unordered_map<int,int> track;
for (int i=0; i<n; i++) {track[inorder[i]] = i;}
return makeTree(preorder, track, 0, 0, n-1);
}
TreeNode* makeTree(vector<int>&preorder,
unordered_map<int,int>& track,
int preBegin,int low,int high){
if (low > high) {return nullptr;}
int inPos = track[preorder[preBegin]];
TreeNode* root = new TreeNode(preorder[preBegin]);
root->left = makeTree(preorder, track,
preBegin+1, low, inPos-1);
root->right = makeTree(preorder, track,
preBegin + inPos-low+1, inPos + 1, high);
return root;
}
};
vector
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() == 0 || inorder.size() == 0) {
return nullptr;
}
TreeNode *root = new TreeNode(preorder[0]);
auto inRootIdx = inorder.size() > 1
? find(inorder.begin(), inorder.end(), preorder[0])
: inorder.begin();
vector<int> inLeft(inorder.begin(), inRootIdx),
inRight(inRootIdx + 1, inorder.end());
vector<int> preLeft(preorder.begin() + 1, preorder.begin() + inLeft.size() + 1),
preRight(preorder.begin() + inLeft.size() + 1, preorder.end());
if (preLeft.size() > 0) {
root->left = buildTree(preLeft, inLeft);
}
if (preRight.size() > 0) {
root->right = buildTree(preRight, inRight);
}
return root;
}
};
2. 循环
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0) return nullptr;
unordered_map<int, int> order;
for(int i = 0;i < inorder.size();i++) order[inorder[i]] = i;
TreeNode* out = new TreeNode(preorder[0]);
stack<TreeNode*> stak;
stak.push(out);
for(int i = 1;i < preorder.size();i++) {
int n = preorder[i];
if(stak.empty()){
out -> right = new TreeNode(n);
stak.push(new TreeNode(n));
} else {
TreeNode* now = stak.top();
if(order[now -> val] > order[n]) {
TreeNode* left = new TreeNode(n);
stak.push(left);
now -> left = left;
} else {
while(!stak.empty() && order[stak.top() -> val] < order[n]) {
now = stak.top();
stak.pop();
}
TreeNode* right = new TreeNode(n);
now -> right = right;
stak.push(right);
}
}
}
return out;
}
};
【Java】
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
递归
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return R(preorder, 0, preorder.length, inorder, 0, inorder.length);
}
private TreeNode R(int[] a, int aBegin, int aEnd, int[] b, int bBegin, int bEnd) {
if (aBegin >= aEnd || bBegin >= bEnd) {return null;}
TreeNode root = new TreeNode(a[aBegin]);
int pivot = bBegin;
for (; pivot<bEnd; pivot++) {if (b[pivot] == a[aBegin]) {break;}}
root.left = R(a, aBegin+1, aBegin+1+pivot-bBegin, b, bBegin, pivot);
root.right = R(a, aBegin+1+pivot-bBegin, aEnd, b, pivot+1, bEnd);
return root;
}
}