34
34
35
35
## 解法
36
36
37
- 前序序列的第一个结点 ` preorder[0] ` 为根节点,我们在中序序列中找到根节点的位置 ` i ` ,可以将中序序列划分为左子树 ` inorder[:i] ` 和右子树 ` inorder[i + 1:] ` 。
37
+ ** 方法一:哈希表 + 递归 **
38
38
39
- 通过左右子树的区间,可以计算出左、右子树节点的个数,假设为 m、n。然后在前序节点中,从根节点往后的 m 个节点为左子树,再往后的 n 个节点为右子树 。
39
+ 由于我们每一次都需要在中序序列中找到根节点的位置,因此我们可以使用哈希表 $d$ 来存储中序序列的值和索引,这样可以将查找的时间复杂度降低到 $O(1)$ 。
40
40
41
- 递归求解即可 。
41
+ 接下来,我们设计一个递归函数 $dfs(i, j, n)$,表示在前序序列中,从第 $i$ 个节点开始的 $n$ 个节点,对应的中序序列中,从第 $j$ 个节点开始的 $n$ 个节点,构造出的二叉树 。
42
42
43
- > 前序遍历:先遍历根节点,再遍历左子树,最后遍历右子树;
44
- >
45
- > 中序遍历:先遍历左子树,再遍历根节点,最后遍历右子树。
43
+ 函数 $dfs(i, j, n)$ 的执行过程如下:
44
+
45
+ 如果 $n = 0$,说明已经没有节点了,返回 $null$;
46
+
47
+ 否则,我们取前序序列的第 $i$ 个节点作为根节点,创建一个树节点,即 ` root = new TreeNode(preorder[i]) ` ,然后我们在中序序列中找到根节点的位置,记为 $k$,则根节点左边的 $k - j$ 个节点为左子树,右边的 $n - k + j - 1$ 个节点为右子树。递归地调用函数 $dfs(i + 1, j, k - j)$ 构造左子树,调用函数 $dfs(i + k - j + 1, k + 1, n - k + j - 1)$ 构造右子树。最后返回根节点 ` root ` 。
48
+
49
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点个数。
46
50
47
51
<!-- tabs:start -->
48
52
59
63
60
64
class Solution :
61
65
def buildTree (self , preorder : List[int ], inorder : List[int ]) -> TreeNode:
62
- if not preorder:
63
- return None
64
- v = preorder[0 ]
65
- root = TreeNode(val = v)
66
- i = inorder.index(v)
67
- root.left = self .buildTree(preorder[1 : 1 + i], inorder[:i])
68
- root.right = self .buildTree(preorder[1 + i :], inorder[i + 1 :])
69
- return root
66
+ def dfs (i , j , n ):
67
+ if n < 1 :
68
+ return None
69
+ root = TreeNode(preorder[i])
70
+ k = d[preorder[i]]
71
+ l = k - j
72
+ root.left = dfs(i + 1 , j, l)
73
+ root.right = dfs(i + 1 + l, k + 1 , n - l - 1 )
74
+ return root
75
+
76
+ d = {v: i for i, v in enumerate (inorder)}
77
+ return dfs(0 , 0 , len (preorder))
70
78
```
71
79
72
80
### ** Java**
@@ -82,52 +90,67 @@ class Solution:
82
90
* }
83
91
*/
84
92
class Solution {
85
- private Map<Integer , Integer > indexes = new HashMap<> ();
93
+ private Map<Integer , Integer > d = new HashMap<> ();
94
+ private int [] preorder;
95
+ private int [] inorder;
86
96
87
97
public TreeNode buildTree (int [] preorder , int [] inorder ) {
88
- for (int i = 0 ; i < inorder. length; ++ i) {
89
- indexes. put(inorder[i], i);
98
+ int n = inorder. length;
99
+ for (int i = 0 ; i < n; ++ i) {
100
+ d. put(inorder[i], i);
90
101
}
91
- return dfs(preorder, inorder, 0 , 0 , preorder. length);
102
+ this . preorder = preorder;
103
+ this . inorder = inorder;
104
+ return dfs(0 , 0 , n);
92
105
}
93
106
94
- private TreeNode dfs (int [] preorder , int [] inorder , int i , int j , int n ) {
95
- if (n <= 0 ) {
107
+ private TreeNode dfs (int i , int j , int n ) {
108
+ if (n < 1 ) {
96
109
return null ;
97
110
}
98
- int v = preorder[i];
99
- int k = indexes . get(v) ;
100
- TreeNode root = new TreeNode (v );
101
- root. left = dfs(preorder, inorder, i + 1 , j, k - j );
102
- root. right = dfs(preorder, inorder, i + 1 + k - j , k + 1 , n - k + j - 1 );
111
+ int k = d . get( preorder[i]) ;
112
+ int l = k - j ;
113
+ TreeNode root = new TreeNode (preorder[i] );
114
+ root. left = dfs(i + 1 , j, l );
115
+ root. right = dfs(i + 1 + l , k + 1 , n - l - 1 );
103
116
return root;
104
117
}
105
118
}
106
119
```
107
120
108
- ### ** JavaScript **
121
+ ### ** C++ **
109
122
110
- ``` js
123
+ ``` cpp
111
124
/* *
112
125
* Definition for a binary tree node.
113
- * function TreeNode(val) {
114
- * this.val = val;
115
- * this.left = this.right = null;
116
- * }
117
- */
118
- /**
119
- * @param {number[]} preorder
120
- * @param {number[]} inorder
121
- * @return {TreeNode}
126
+ * struct TreeNode {
127
+ * int val;
128
+ * TreeNode *left;
129
+ * TreeNode *right;
130
+ * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
131
+ * };
122
132
*/
123
- var buildTree = function (preorder , inorder ) {
124
- if (preorder .length == 0 ) return null ;
125
- const v = preorder[0 ];
126
- const root = new TreeNode (v);
127
- const i = inorder .indexOf (v);
128
- root .left = buildTree (preorder .slice (1 , 1 + i), inorder .slice (0 , i));
129
- root .right = buildTree (preorder .slice (1 + i), inorder .slice (1 + i));
130
- return root;
133
+ class Solution {
134
+ public:
135
+ TreeNode* buildTree(vector<int >& preorder, vector<int >& inorder) {
136
+ unordered_map<int, int> d;
137
+ int n = inorder.size();
138
+ for (int i = 0; i < n; ++i) {
139
+ d[ inorder[ i]] = i;
140
+ }
141
+ function<TreeNode* (int, int, int)> dfs = [ &] (int i, int j, int n) -> TreeNode* {
142
+ if (n < 1) {
143
+ return nullptr;
144
+ }
145
+ int k = d[ preorder[ i]] ;
146
+ int l = k - j;
147
+ TreeNode* root = new TreeNode(preorder[ i] );
148
+ root->left = dfs(i + 1, j, l);
149
+ root->right = dfs(i + 1 + l, k + 1, n - l - 1);
150
+ return root;
151
+ };
152
+ return dfs(0, 0, n);
153
+ }
131
154
};
132
155
```
133
156
@@ -143,56 +166,59 @@ var buildTree = function (preorder, inorder) {
143
166
* }
144
167
*/
145
168
func buildTree(preorder []int, inorder []int) *TreeNode {
146
- indexes := make ( map [int ]int )
169
+ d := map[int]int{}
147
170
for i, v := range inorder {
148
- indexes [v] = i
171
+ d [v] = i
149
172
}
150
173
var dfs func(i, j, n int) *TreeNode
151
174
dfs = func(i, j, n int) *TreeNode {
152
- if n <= 0 {
175
+ if n < 1 {
153
176
return nil
154
177
}
155
- v := preorder[i]
156
- k := indexes[v]
157
- root := &TreeNode{Val: v }
158
- root.Left = dfs (i+1 , j, k-j )
159
- root.Right = dfs (i+1 +k-j , k+1 , n-k+j -1 )
178
+ k := d[ preorder[i] ]
179
+ l := k - j
180
+ root := &TreeNode{Val: preorder[i] }
181
+ root.Left = dfs(i+1, j, l )
182
+ root.Right = dfs(i+1+l , k+1, n-l -1)
160
183
return root
161
184
}
162
185
return dfs(0, 0, len(inorder))
163
186
}
164
187
```
165
188
166
- ### ** C++ **
189
+ ### ** JavaScript **
167
190
168
- ``` cpp
191
+ ``` js
169
192
/**
170
193
* Definition for a binary tree node.
171
- * struct TreeNode {
172
- * int val;
173
- * TreeNode *left;
174
- * TreeNode *right;
175
- * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
176
- * };
194
+ * function TreeNode(val) {
195
+ * this.val = val;
196
+ * this.left = this.right = null;
197
+ * }
177
198
*/
178
- class Solution {
179
- public:
180
- unordered_map<int, int> indexes;
181
-
182
- TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
183
- for (int i = 0; i < inorder.size(); ++i) indexes[inorder[i]] = i;
184
- return dfs(preorder, inorder, 0, 0, inorder.size());
199
+ /**
200
+ * @param {number[]} preorder
201
+ * @param {number[]} inorder
202
+ * @return {TreeNode}
203
+ */
204
+ var buildTree = function (preorder , inorder ) {
205
+ const d = new Map ();
206
+ const n = inorder .length ;
207
+ for (let i = 0 ; i < n; ++ i) {
208
+ d .set (inorder[i], i);
185
209
}
186
-
187
- TreeNode* dfs (vector<int >& preorder, vector<int >& inorder, int i, int j, int n) {
188
- if (n <= 0) return nullptr;
189
- int v = preorder[ i] ;
190
- int k = indexes[ v] ;
191
- TreeNode* root = new TreeNode(v);
192
- root->left = dfs(preorder, inorder, i + 1, j, k - j);
193
- root->right = dfs(preorder, inorder, i + 1 + k - j, k + 1, n - k + j - 1);
210
+ const dfs = (i , j , n ) => {
211
+ if (n < 1 ) {
212
+ return null ;
213
+ }
214
+ const k = d .get (preorder[i]);
215
+ const l = k - j;
216
+ const root = new TreeNode (preorder[i]);
217
+ root .left = dfs (i + 1 , j, l);
218
+ root .right = dfs (i + 1 + l, k + 1 , n - l - 1 );
194
219
return root;
195
- }
220
+ };
221
+ return dfs (0 , 0 , n);
196
222
};
197
223
```
198
224
@@ -214,16 +240,23 @@ public:
214
240
*/
215
241
216
242
function buildTree(preorder : number [], inorder : number []): TreeNode | null {
217
- if (preorder.length == 0) return null;
218
- let val: number = preorder[0];
219
- let node: TreeNode = new TreeNode(val);
220
- let index: number = inorder.indexOf(val);
221
- node.left = buildTree(
222
- preorder.slice(1, index + 1),
223
- inorder.slice(0, index),
224
- );
225
- node.right = buildTree(preorder.slice(index + 1), inorder.slice(index + 1));
226
- return node;
243
+ const d = new Map <number , number >();
244
+ const n = inorder .length ;
245
+ for (let i = 0 ; i < n ; ++ i ) {
246
+ d .set (inorder [i ], i );
247
+ }
248
+ const dfs = (i : number , j : number , n : number ): TreeNode | null => {
249
+ if (n < 1 ) {
250
+ return null ;
251
+ }
252
+ const k = d .get (preorder [i ]) ?? 0 ;
253
+ const l = k - j ;
254
+ const root = new TreeNode (preorder [i ]);
255
+ root .left = dfs (i + 1 , j , l );
256
+ root .right = dfs (i + 1 + l , k + 1 , n - l - 1 );
257
+ return root ;
258
+ };
259
+ return dfs (0 , 0 , n );
227
260
}
228
261
```
229
262
0 commit comments