@@ -118,11 +118,9 @@ class Solution:
118
118
class Solution {
119
119
private Map<Integer , Integer > pos = new HashMap<> ();
120
120
private int [] preorder;
121
- private int [] postorder;
122
121
123
122
public TreeNode constructFromPrePost (int [] preorder , int [] postorder ) {
124
123
this . preorder = preorder;
125
- this . postorder = postorder;
126
124
for (int i = 0 ; i < postorder. length; ++ i) {
127
125
pos. put(postorder[i], i);
128
126
}
@@ -259,4 +257,204 @@ function constructFromPrePost(preorder: number[], postorder: number[]): TreeNode
259
257
260
258
<!-- tabs: end -->
261
259
260
+ ### 方法二:递归的另一种写法
261
+
262
+ 我们也可以设计一个递归函数 $dfs(i, j, n)$,其中 $i$ 和 $j$ 表示前序遍历和后序遍历的起点,而 $n$ 表示节点个数。这个函数的功能是根据前序遍历 $[ i, i + n - 1] $ 和后序遍历 $[ j, j + n - 1] $ 构造出二叉树的根节点。那么答案就是 $dfs(0, 0, n)$,其中 $n$ 是前序遍历的长度。
263
+
264
+ 函数 $dfs(i, j, n)$ 的执行步骤如下:
265
+
266
+ 1 . 如果 $n = 0$,说明范围为空,直接返回空节点。
267
+ 1 . 否则,我们构造一个新的节点 $root$,它的值为前序遍历中的第一个节点的值,也就是 $preorder[ i] $。
268
+ 1 . 如果 $n = 1$,说明 $root$ 没有左子树也没有右子树,直接返回 $root$。
269
+ 1 . 否则,左子树的根节点的值为 $preorder[ i + 1] $,我们在后序遍历中找到 $preorder[ i + 1] $ 的位置,记为 $k$。那么左子树的节点个数 $m = k - j + 1$,右子树的节点数为 $n - m - 1$。我们递归地重建左右子树,然后将左右子树的根节点分别作为 $root$ 的左右子节点。最后返回 $root$。
270
+
271
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是节点数。
272
+
273
+ <!-- tabs: start -->
274
+
275
+ ``` python
276
+ # Definition for a binary tree node.
277
+ # class TreeNode:
278
+ # def __init__(self, val=0, left=None, right=None):
279
+ # self.val = val
280
+ # self.left = left
281
+ # self.right = right
282
+ class Solution :
283
+ def constructFromPrePost (
284
+ self , preorder : List[int ], postorder : List[int ]
285
+ ) -> Optional[TreeNode]:
286
+ def dfs (i : int , j : int , n : int ) -> Optional[TreeNode]:
287
+ if n <= 0 :
288
+ return None
289
+ root = TreeNode(preorder[i])
290
+ if n == 1 :
291
+ return root
292
+ k = pos[preorder[i + 1 ]]
293
+ m = k - j + 1
294
+ root.left = dfs(i + 1 , j, m)
295
+ root.right = dfs(i + m + 1 , k + 1 , n - m - 1 )
296
+ return root
297
+
298
+ pos = {x: i for i, x in enumerate (postorder)}
299
+ return dfs(0 , 0 , len (preorder))
300
+ ```
301
+
302
+ ``` java
303
+ /**
304
+ * Definition for a binary tree node.
305
+ * public class TreeNode {
306
+ * int val;
307
+ * TreeNode left;
308
+ * TreeNode right;
309
+ * TreeNode() {}
310
+ * TreeNode(int val) { this.val = val; }
311
+ * TreeNode(int val, TreeNode left, TreeNode right) {
312
+ * this.val = val;
313
+ * this.left = left;
314
+ * this.right = right;
315
+ * }
316
+ * }
317
+ */
318
+ class Solution {
319
+ private Map<Integer , Integer > pos = new HashMap<> ();
320
+ private int [] preorder;
321
+
322
+ public TreeNode constructFromPrePost (int [] preorder , int [] postorder ) {
323
+ this . preorder = preorder;
324
+ for (int i = 0 ; i < postorder. length; ++ i) {
325
+ pos. put(postorder[i], i);
326
+ }
327
+ return dfs(0 , 0 , preorder. length);
328
+ }
329
+
330
+ private TreeNode dfs (int i , int j , int n ) {
331
+ if (n <= 0 ) {
332
+ return null ;
333
+ }
334
+ TreeNode root = new TreeNode (preorder[i]);
335
+ if (n == 1 ) {
336
+ return root;
337
+ }
338
+ int k = pos. get(preorder[i + 1 ]);
339
+ int m = k - j + 1 ;
340
+ root. left = dfs(i + 1 , j, m);
341
+ root. right = dfs(i + m + 1 , k + 1 , n - m - 1 );
342
+ return root;
343
+ }
344
+ }
345
+ ```
346
+
347
+ ``` cpp
348
+ /* *
349
+ * Definition for a binary tree node.
350
+ * struct TreeNode {
351
+ * int val;
352
+ * TreeNode *left;
353
+ * TreeNode *right;
354
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
355
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
356
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
357
+ * };
358
+ */
359
+ class Solution {
360
+ public:
361
+ TreeNode* constructFromPrePost(vector<int >& preorder, vector<int >& postorder) {
362
+ unordered_map<int, int> pos;
363
+ int n = postorder.size();
364
+ for (int i = 0; i < n; ++i) {
365
+ pos[ postorder[ i]] = i;
366
+ }
367
+ function<TreeNode* (int, int, int)> dfs = [ &] (int i, int j, int n) -> TreeNode* {
368
+ if (n <= 0) {
369
+ return nullptr;
370
+ }
371
+ TreeNode* root = new TreeNode(preorder[ i] );
372
+ if (n == 1) {
373
+ return root;
374
+ }
375
+ int k = pos[ preorder[ i + 1]] ;
376
+ int m = k - j + 1;
377
+ root->left = dfs(i + 1, j, m);
378
+ root->right = dfs(i + m + 1, k + 1, n - m - 1);
379
+ return root;
380
+ };
381
+ return dfs(0, 0, n);
382
+ }
383
+ };
384
+ ```
385
+
386
+ ```go
387
+ /**
388
+ * Definition for a binary tree node.
389
+ * type TreeNode struct {
390
+ * Val int
391
+ * Left *TreeNode
392
+ * Right *TreeNode
393
+ * }
394
+ */
395
+ func constructFromPrePost(preorder []int, postorder []int) *TreeNode {
396
+ pos := map[int]int{}
397
+ for i, x := range postorder {
398
+ pos[x] = i
399
+ }
400
+ var dfs func(int, int, int) *TreeNode
401
+ dfs = func(i, j, n int) *TreeNode {
402
+ if n <= 0 {
403
+ return nil
404
+ }
405
+ root := &TreeNode{Val: preorder[i]}
406
+ if n == 1 {
407
+ return root
408
+ }
409
+ k := pos[preorder[i+1]]
410
+ m := k - j + 1
411
+ root.Left = dfs(i+1, j, m)
412
+ root.Right = dfs(i+m+1, k+1, n-m-1)
413
+ return root
414
+ }
415
+ return dfs(0, 0, len(preorder))
416
+ }
417
+ ```
418
+
419
+ ``` ts
420
+ /**
421
+ * Definition for a binary tree node.
422
+ * class TreeNode {
423
+ * val: number
424
+ * left: TreeNode | null
425
+ * right: TreeNode | null
426
+ * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
427
+ * this.val = (val===undefined ? 0 : val)
428
+ * this.left = (left===undefined ? null : left)
429
+ * this.right = (right===undefined ? null : right)
430
+ * }
431
+ * }
432
+ */
433
+
434
+ function constructFromPrePost(preorder : number [], postorder : number []): TreeNode | null {
435
+ const pos: Map <number , number > = new Map ();
436
+ const n = postorder .length ;
437
+ for (let i = 0 ; i < n ; ++ i ) {
438
+ pos .set (postorder [i ], i );
439
+ }
440
+ const dfs = (i : number , j : number , n : number ): TreeNode | null => {
441
+ if (n <= 0 ) {
442
+ return null ;
443
+ }
444
+ const root = new TreeNode (preorder [i ]);
445
+ if (n === 1 ) {
446
+ return root ;
447
+ }
448
+ const k = pos .get (preorder [i + 1 ])! ;
449
+ const m = k - j + 1 ;
450
+ root .left = dfs (i + 1 , j , m );
451
+ root .right = dfs (i + 1 + m , k + 1 , n - 1 - m );
452
+ return root ;
453
+ };
454
+ return dfs (0 , 0 , n );
455
+ }
456
+ ```
457
+
458
+ <!-- tabs: end -->
459
+
262
460
<!-- end -->
0 commit comments