-
Notifications
You must be signed in to change notification settings - Fork 21
/
145. Binary Tree Postorder Traversal.java
executable file
·134 lines (112 loc) · 3.79 KB
/
145. Binary Tree Postorder Traversal.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
M
tags: Stack, Two Stacks, Tree
time: O(n)
space: O(n)
如题, POST-ORDER traversal.
LeetCode给了hard, 应该是觉得stack的做法比较难想到.
#### Method1: DFS, Recursive
- trivial, 先加left recursively, 再加right recursively, 然后组成头部.
- Option1 w/o helper; option2 with dfs helper.
#### Method2, Iterative, Stack
- Option1: reversely add to list
- 双stack的思想, 需要在图纸上画一画
- 原本需要的顺序是: 先leftChild, rightChild, currNode.
- 营造一个stack, reversely process: 先currNode, 再rightChild, 再leftChild
- 这样出来的结果是reverse的, 那么翻转一下就可以了.
- reverse add: `list.add(0, x)`;
- 利用stack的特点
- 每次加element进stack的时候, 想要在 bottom/后process的, 先加
- 想要下一轮立刻process的, 最后push进stack.
- Option2: regular sequence add to stack: add curr, right, left
- Use set to contain the processed children
- only process curr if its children is processed
```
/*
Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values.
Example
Given binary tree {1,#,2,3},
1
\
2
/
3
return [3,2,1].
Challenge
Can you do it without recursion?
Tags Expand
Binary Tree
*/
// Method1, Option1: dfs w/o helper. always add left, add right, then add middle
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> rst = new ArrayList<>();
if (root == null) return rst;
rst.addAll(postorderTraversal(root.left));
rst.addAll(postorderTraversal(root.right));
rst.add(root.val);
return rst;
}
}
// Method1, Option2: recursive with dfs helper
public class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> rst = new ArrayList<>();
dfs(rst, root);
return rst;
}
public void dfs(List<Integer>rst, TreeNode node) {
if (node == null) return;
dfs(rst, node.left);
dfs(rst, node.right);
rst.add(node.val);
}
}
// Simpler version, add to begining of list.
// V2
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> rst = new ArrayList<>();
if (root == null) return rst;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
rst.add(0, node.val);
if (node.left != null) stack.push(node.left);
if (node.right != null) stack.push(node.right);
}
return rst;
}
}
// Method2, Iterative, Option2: regular sequence add to stack: add curr, right, left
// only process curr if its children is processed
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> rst = new ArrayList<>();
if (root == null) return rst;
Stack<TreeNode> stack = new Stack<>();
Set<TreeNode> set = new HashSet<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.peek();
if (validate(set, node)) {
stack.pop();
rst.add(node.val);
set.add(node);
continue;
}
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left);
}
return rst;
}
private boolean validate(Set<TreeNode> set, TreeNode node) {
if(node.left == null && node.right == null) return true;
boolean left = set.contains(node.left), right = set.contains(node.right);
if (left && right) return true;
if ((node.left == null && right) || (node.right == null && left)) return true;
return false;
}
}
```