Skip to content

Commit 4a37a7a

Browse files
committed
105. 从前序与中序遍历序列构造二叉树
1 parent 986c1f8 commit 4a37a7a

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

leetcode_Java/DoneTitle.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
101. 对称二叉树
33
102. 二叉树的层序遍历
44
104. 二叉树的最大深度
5+
105. 从前序与中序遍历序列构造二叉树
56
114. 二叉树展开为链表
67
144. 二叉树的前序遍历
78
145. 二叉树的后序遍历

leetcode_Java/Solution0105.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// 从前序与中序遍历序列构造二叉树
2+
3+
4+
/**
5+
* Definition for a binary tree node.
6+
* public class TreeNode {
7+
* int val;
8+
* TreeNode left;
9+
* TreeNode right;
10+
* TreeNode() {}
11+
* TreeNode(int val) { this.val = val; }
12+
* TreeNode(int val, TreeNode left, TreeNode right) {
13+
* this.val = val;
14+
* this.left = left;
15+
* this.right = right;
16+
* }
17+
* }
18+
*/
19+
20+
21+
/**
22+
* 递归思路:
23+
* 1、方法功能:入参是两个数组,两个数组都为空时返回空,不为空时创建、返回根节点
24+
* 2、递归逻辑:
25+
* 1)根据前、中序数组的特点,拆分出左子树和右子树两部分数组
26+
* 2)左右子树的数组同样可以调用这个方法,得到左右子树的根节点
27+
* 3)上一层使用下一层的结果,取下一层左子树的根节点作为当前层的左子节点,取下一层右子树的根节点作为当前层的右子节点
28+
*/
29+
class Solution {
30+
public TreeNode buildTree(int[] preorder, int[] inorder) {
31+
if (preorder.length == 0 && inorder.length == 0) {
32+
return null;
33+
}
34+
TreeNode root = new TreeNode(preorder[0]);
35+
int index = Arrays.asList(Arrays.stream(inorder).boxed().toArray(Integer[]::new)).indexOf(preorder[0]);
36+
root.left = buildTree(Arrays.copyOfRange(preorder, 1, index + 1), Arrays.copyOfRange(inorder, 0, index));
37+
root.right = buildTree(Arrays.copyOfRange(preorder, index + 1, preorder.length), Arrays.copyOfRange(inorder, index + 1, inorder.length));
38+
return root;
39+
}
40+
}
41+
42+
43+
/**
44+
* 递归思路:
45+
* 1、数据结构:
46+
* 1)使用Map存放中序数组的元素和索引,方便直接获取索引,避免了重复遍历获取
47+
* 2)使用指针表示数组的开始和结束位置,避免了数组的拆分和拷贝,节省额外空间。注意两个指针指向的数组范围是包括左边界,不包括右边界
48+
* 2、递归逻辑:
49+
* 1)原方法入参不够用,创建一个新的方法作为递归方法
50+
* 2)方法的功能:终止条件,当数组为空时,前序起始、结束指针位置相同,返回空;不为空时创建、返回根节点
51+
* 3)通过指针划分左右子树的数组范围,调用同个方法得到左右子树的根节点
52+
* 4)上一层使用下一层的结果,取下一层左子树的根节点作为当前层的左子节点,取下一层右子树的根节点作为当前层的右子节点
53+
*/
54+
class Solution {
55+
public TreeNode buildTree(int[] preorder, int[] inorder) {
56+
Map<Integer, Integer> map = new HashMap<>();
57+
for (int i = 0; i < inorder.length; i++) {
58+
map.put(inorder[i], i);
59+
}
60+
return buildTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length, map);
61+
}
62+
63+
public TreeNode buildTreeHelper(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end, Map<Integer, Integer> map) {
64+
if (p_start == p_end) {
65+
return null;
66+
}
67+
int root_val = preorder[p_start];
68+
TreeNode root = new TreeNode(root_val);
69+
int i_root_index = map.get(root_val);
70+
int left_num = i_root_index - i_start;
71+
root.left = buildTreeHelper(preorder, p_start + 1, p_start + left_num + 1, inorder, i_start, i_root_index, map);
72+
root.right = buildTreeHelper(preorder, p_start + left_num + 1, p_end, inorder, i_root_index + 1, i_end, map);
73+
return root;
74+
}
75+
}

0 commit comments

Comments
 (0)