2
2
3
3
## 题目描述
4
4
5
- 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
5
+ < p > 输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。</ p >
6
6
7
- 例如,给出
7
+ < p >假设输入的前序遍历和中序遍历的结果中都不含重复的数字。</ p >
8
8
9
- ```
10
- 前序遍历 preorder = [3,9,20,15,7]
11
- 中序遍历 inorder = [9,3,15,20,7]
12
- ```
9
+ <p > </p >
13
10
14
- 返回如下的二叉树:
11
+ <p ><strong >示例 1:</strong ></p >
12
+ <img alt =" " src =" https://cdn.jsdelivr.net/gh/doocs/leetcode@main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9807.%20%E9%87%8D%E5%BB%BA%E4%BA%8C%E5%8F%89%E6%A0%91/images/tree.jpg " />
13
+ <pre >
14
+ <strong >Input:</strong > preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
15
+ <strong >Output:</strong > [3,9,20,null,null,15,7]
16
+ </pre >
15
17
16
- ```
17
- 3
18
- / \
19
- 9 20
20
- / \
21
- 15 7
22
- ```
18
+ <p ><strong >示例 2:</strong ></p >
19
+
20
+ <pre >
21
+ <strong >Input:</strong > preorder = [-1], inorder = [-1]
22
+ <strong >Output:</strong > [-1]
23
+ </pre >
24
+
25
+ <p > </p >
26
+
27
+ <p ><strong >限制:</strong ></p >
28
+
29
+ <p ><code >0 <= 节点个数 <= 5000</code ></p >
23
30
24
- ** 限制: **
31
+ < p > </ p >
25
32
26
- - ` 0 <= 节点个数 <= 5000 `
33
+ < p >< strong >注意</ strong >:本题与主站 105 题重复:< a href = " https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ " >https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/</ a ></ p >
27
34
28
35
## 解法
29
36
37
+ 前序序列的第一个结点 ` preorder[0] ` 为根节点,我们在中序序列中找到根节点的位置 i,可以将中序序列划分为左子树 ` inorder[:i] ` 、右子树 ` inorder[i+1:] ` 。
38
+
39
+ 通过左右子树的区间,可以计算出左、右子树节点的个数,假设为 m、n。然后在前序节点中,从根节点往后的 m 个节点为左子树,再往后的 n 个节点为右子树。
40
+
41
+ 递归求解即可。
42
+
43
+ > 前序遍历:先遍历根节点,再遍历左右子树;中序遍历:先遍历左子树,再遍历根节点,最后遍历右子树。
44
+
30
45
<!-- tabs:start -->
31
46
32
47
### ** Python3**
40
55
# self.right = None
41
56
42
57
class Solution :
43
- indexes = {}
44
58
def buildTree (self , preorder : List[int ], inorder : List[int ]) -> TreeNode:
45
- def build (preorder , inorder , p1 , p2 , i1 , i2 ) -> TreeNode:
46
- if p1 > p2 or i1 > i2:
47
- return None
48
- root_val = preorder[p1]
49
- pos = self .indexes[root_val]
50
- root = TreeNode(root_val)
51
- root.left = None if pos == i1 else build(preorder, inorder, p1 + 1 , p1 - i1 + pos, i1, pos - 1 )
52
- root.right = None if pos == i2 else build(preorder, inorder, p1 - i1 + pos + 1 , p2, pos + 1 , i2)
53
- return root
54
- n = len (inorder)
55
- for i in range (n):
56
- self .indexes[inorder[i]] = i
57
- return build(preorder, inorder, 0 , n - 1 , 0 , n - 1 )
59
+ if not preorder:
60
+ return None
61
+ v = preorder[0 ]
62
+ root = TreeNode(val = v)
63
+ i = inorder.index(v)
64
+ root.left = self .buildTree(preorder[1 :1 + i], inorder[:i])
65
+ root.right = self .buildTree(preorder[1 + i:], inorder[i + 1 :])
66
+ return root
58
67
```
59
68
60
69
### ** Java**
@@ -73,21 +82,22 @@ class Solution {
73
82
private Map<Integer , Integer > indexes = new HashMap<> ();
74
83
75
84
public TreeNode buildTree (int [] preorder , int [] inorder ) {
76
- int n = inorder. length;
77
- for (int i = 0 ; i < n; ++ i) {
85
+ for (int i = 0 ; i < inorder. length; ++ i) {
78
86
indexes. put(inorder[i], i);
79
87
}
80
- return build (preorder, inorder, 0 , n - 1 , 0 , n - 1 );
88
+ return dfs (preorder, inorder, 0 , 0 , preorder . length );
81
89
}
82
90
83
- private TreeNode build (int [] preorder , int [] inorder , int p1 , int p2 , int i1 , int i2 ) {
84
- if (p1 > p2 || i1 > i2) return null ;
85
- int rootVal = preorder[p1];
86
- int pos = indexes. get(rootVal);
87
- TreeNode node = new TreeNode (rootVal);
88
- node. left = pos == i1 ? null : build(preorder, inorder, p1 + 1 , pos - i1 + p1, i1, pos - 1 );
89
- node. right = pos == i2 ? null : build(preorder, inorder, pos - i1 + p1 + 1 , p2, pos + 1 , i2);
90
- return node;
91
+ private TreeNode dfs (int [] preorder , int [] inorder , int i , int j , int n ) {
92
+ if (n <= 0 ) {
93
+ return null ;
94
+ }
95
+ int v = preorder[i];
96
+ int k = indexes. get(v);
97
+ TreeNode root = new TreeNode (v);
98
+ root. left = dfs(preorder, inorder, i + 1 , j, k - j);
99
+ root. right = dfs(preorder, inorder, i + 1 + k - j, k + 1 , n - k + j - 1 );
100
+ return root;
91
101
}
92
102
}
93
103
```
@@ -108,25 +118,13 @@ class Solution {
108
118
* @return {TreeNode}
109
119
*/
110
120
var buildTree = function (preorder , inorder ) {
111
- if (! preorder || ! preorder .length ) return null ;
112
- let preIdx = 0 ;
113
- let inMap = {};
114
- for (let i = 0 ; i < inorder .length ; i++ ) {
115
- inMap[inorder[i]] = i;
116
- }
117
- function func (start , end ) {
118
- if (start > end) {
119
- return null ;
120
- }
121
- let preVal = preorder[preIdx];
122
- preIdx++ ;
123
- let inIdx = inMap[preVal];
124
- let node = new TreeNode (preVal);
125
- node .left = func (start, inIdx - 1 );
126
- node .right = func (inIdx + 1 , end);
127
- return node;
128
- }
129
- return func (0 , preorder .length - 1 );
121
+ if (preorder .length == 0 ) return null ;
122
+ const v = preorder[0 ];
123
+ const root = new TreeNode (v);
124
+ const i = inorder .indexOf (v);
125
+ root .left = buildTree (preorder .slice (1 , 1 + i), inorder .slice (0 , i));
126
+ root .right = buildTree (preorder .slice (1 + i), inorder .slice (1 + i));
127
+ return root;
130
128
};
131
129
```
132
130
@@ -142,47 +140,55 @@ var buildTree = function (preorder, inorder) {
142
140
* }
143
141
*/
144
142
func buildTree (preorder []int , inorder []int ) *TreeNode {
145
- return helper (preorder, inorder, 0 , 0 , len (preorder)-1 )
146
- }
147
-
148
- func helper (preorder , inorder []int , index , start , end int ) *TreeNode {
149
- if start > end {
150
- return nil
151
- }
152
- root := &TreeNode{Val:preorder[index]}
153
- j := start
154
- for j < end && preorder[index] != inorder[j] {
155
- j++
156
- }
157
- root.Left = helper (preorder, inorder, index + 1 , start, j - 1 )
158
- root.Right = helper (preorder, inorder, index + 1 + j -start, j + 1 , end)
159
- return root
143
+ indexes := make (map [int ]int )
144
+ for i , v := range inorder {
145
+ indexes[v] = i
146
+ }
147
+ var dfs func (i, j, n int ) *TreeNode
148
+ dfs = func (i, j, n int ) *TreeNode {
149
+ if n <= 0 {
150
+ return nil
151
+ }
152
+ v := preorder[i]
153
+ k := indexes[v]
154
+ root := &TreeNode{Val: v}
155
+ root.Left = dfs (i+1 , j, k-j)
156
+ root.Right = dfs (i+1 +k-j, k+1 , n-k+j-1 )
157
+ return root
158
+ }
159
+ return dfs (0 , 0 , len (inorder))
160
160
}
161
161
```
162
162
163
163
### ** C++**
164
164
165
165
``` cpp
166
+ /* *
167
+ * Definition for a binary tree node.
168
+ * struct TreeNode {
169
+ * int val;
170
+ * TreeNode *left;
171
+ * TreeNode *right;
172
+ * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
173
+ * };
174
+ */
166
175
class Solution {
167
176
public:
177
+ unordered_map<int, int> indexes;
178
+
168
179
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
169
- return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
180
+ for (int i = 0; i < inorder.size(); ++i) indexes[inorder[i]] = i;
181
+ return dfs(preorder, inorder, 0, 0, inorder.size());
170
182
}
171
183
172
- private:
173
- TreeNode* build(vector<int >& preorder, vector<int >& inorder, int pre_l, int pre_r, int in_l, int in_r) {
174
- if (pre_l > pre_r || in_l > in_r) {
175
- return NULL;
176
- }
177
- int root = preorder[ pre_l] ;
178
- int i = in_l;
179
- while (i <= in_r && inorder[ i] != root) {
180
- ++i;
181
- }
182
- TreeNode* node = new TreeNode(root);
183
- node->left = build(preorder, inorder, pre_l + 1, pre_l + i - in_l, in_l, i - 1);
184
- node->right = build(preorder, inorder, pre_l + i - in_l + 1, pre_r, i + 1, in_r);
185
- return node;
184
+ TreeNode* dfs (vector<int >& preorder, vector<int >& inorder, int i, int j, int n) {
185
+ if (n <= 0) return nullptr;
186
+ int v = preorder[ i] ;
187
+ int k = indexes[ v] ;
188
+ TreeNode* root = new TreeNode(v);
189
+ root->left = dfs(preorder, inorder, i + 1, j, k - j);
190
+ root->right = dfs(preorder, inorder, i + 1 + k - j, k + 1, n - k + j - 1);
191
+ return root;
186
192
}
187
193
};
188
194
```
0 commit comments