Skip to content

Commit b4ec29a

Browse files
authored
feat: add solutions to lc problem: No.0889 (doocs#2364)
No.0889.Construct Binary Tree from Preorder and Postorder Traversal
1 parent c05119c commit b4ec29a

File tree

8 files changed

+541
-15
lines changed

8 files changed

+541
-15
lines changed

solution/0800-0899/0889.Construct Binary Tree from Preorder and Postorder Traversal/README.md

+200-2
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,9 @@ class Solution:
118118
class Solution {
119119
private Map<Integer, Integer> pos = new HashMap<>();
120120
private int[] preorder;
121-
private int[] postorder;
122121

123122
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
124123
this.preorder = preorder;
125-
this.postorder = postorder;
126124
for (int i = 0; i < postorder.length; ++i) {
127125
pos.put(postorder[i], i);
128126
}
@@ -259,4 +257,204 @@ function constructFromPrePost(preorder: number[], postorder: number[]): TreeNode
259257

260258
<!-- tabs:end -->
261259

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+
262460
<!-- end -->

0 commit comments

Comments
 (0)