Article Directory
Jianzhi offer 07 Rebuild the binary tree
Enter the results of pre-order traversal and mid-order traversal of a binary tree, and please rebuild the binary tree. Assume that the input result of pre-order traversal and middle-order traversal does not contain repeated numbers.
For example, given
Preorder traversal preorder = [3,9,20,15,7] Inorder
traversal inorder = [9,3,15,20,7]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
limit:
0 <= number of nodes <= 5000 0 <= number of nodes <= 5000 0<=Section point a number<=5000
注意:
This question is the same as the 105 question of the main site: https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
前置知识:
If there are repeated numbers, the pre-order and middle-order cannot determine a binary tree, because the repeated numbers in the pre-order sequence correspond to which of the same repeated numbers in the middle-order sequence, which makes it impossible to judge the left and right nodes in the current pre-order sequence. node.
Problem-solving ideas
The first value of the preorder traversal is the value of the root node. Use this value to divide the middle order traversal result into two parts. The left part is the left subtree middle order traversal result of the tree, and the right part is the right subtree middle order traversal result of the tree. the result of. Then the left and right subtrees are solved recursively.
- First use
HashMap
toinorder
save the sequence ( the index position of thekey:
node'sval
value:
node in the sequence), and thenHashMap
findinorder
the position of the root node in the sequence according to it. - The root node
val
inHashMap
the root node is a value correspondinginorder
position in the sequence. - Then the tree can be built recursively according to the number of nodes on the left and right sides of the root node in the middle order.
Java code
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder==null || preorder.length==0) return null;//preorder.length==0的话,inorder.length肯定也为0,所以只判断一个即可
HashMap<Integer ,Integer> hashmap = new HashMap<>();
for(int i = 0;i<inorder.length;i++){
//将中序的信息存入HashMap,方便后面根据根节点分割左右子树
hashmap.put(inorder[i],i);
}
return dfs(preorder,0,preorder.length-1,0,hashmap);
}
//pl即preorder left,即前序数组的左边界,pr即前序数组的右边界,同理il即中序的左边界
public TreeNode dfs(int[] preorder,int pl,int pr,int il,HashMap<Integer ,Integer> hashmap){
if(pl>pr) return null;//递归终止条件,前序数组中没有元素了
TreeNode curRoot = new TreeNode(preorder[pl]);//当次递归的根节点
int k = hashmap.get(curRoot.val);//当前根节点在中序数组中的索引
curRoot.left = dfs(preorder,pl+1,pl+(k-il),il,hashmap); //k-il即当前递归栈中序中左子树的结点个数
curRoot.right = dfs(preorder,pl+(k-il)+1,pr,k+1,hashmap);
return curRoot;
}
}