Skip to content

Commit 381435a

Browse files
committed
feat: add solutions to lc problem: No.0145.Binary Tree Postorder
Traversal
1 parent 3f722ef commit 381435a

File tree

7 files changed

+529
-97
lines changed

7 files changed

+529
-97
lines changed

solution/0000-0099/0094.Binary Tree Inorder Traversal/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
3. 左节点为空时,弹出栈顶元素并处理
7676
4. 重复 2-3 的操作
7777

78-
**3. Morris 实现前序遍历**
78+
**3. Morris 实现中序遍历**
7979

8080
Morris 遍历无需使用栈,空间复杂度为 O(1)。核心思想是:
8181

solution/0100-0199/0145.Binary Tree Postorder Traversal/README.md

+216-40
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,36 @@
2121

2222
<p><strong>进阶:</strong>&nbsp;递归算法很简单,你可以通过迭代算法完成吗?</p>
2323

24-
2524
## 解法
2625

2726
<!-- 这里可写通用的实现逻辑 -->
2827

29-
递归遍历或利用栈实现非递归遍历。
28+
**1. 递归遍历**
29+
30+
先递归左右子树,再访问根节点。
31+
32+
**2. 栈实现非递归遍历**
3033

3134
非递归的思路如下:
3235

3336
先序遍历的顺序是:头、左、右,如果我们改变左右孩子的顺序,就能将顺序变成:头、右、左。
3437

35-
我们先不打印头节点,而是存放到另一个收集栈 s2 中,最后遍历结束,输出收集栈元素,即是后序遍历:左、右、头。
38+
我们先不打印头节点,而是存放到另一个收集栈 res 中,最后遍历结束,输出收集栈元素,即是后序遍历:左、右、头。收集栈是为了实现结果列表的逆序。我们也可以直接使用链表,每次插入元素时,放在头部,最后直接返回链表即可,无需进行逆序。
39+
40+
**3. Morris 实现后序遍历**
41+
42+
Morris 遍历无需使用栈,空间复杂度为 O(1)。核心思想是:
43+
44+
遍历二叉树节点,
45+
46+
1. 若当前节点 root 的右子树为空,**将当前节点值添加至结果列表 res** 中,并将当前节点更新为 `root.left`
47+
2. 若当前节点 root 的右子树不为空,找到右子树的最左节点 next(也即是 root 节点在中序遍历下的后继节点):
48+
- 若后继节点 next 的左子树为空,**将当前节点值添加至结果列表 res** 中,然后将后继节点的左子树指向当前节点 root,并将当前节点更新为 `root.right`
49+
- 若后继节点 next 的左子树不为空,将后继节点左子树指向空(即解除 next 与 root 的指向关系),并将当前节点更新为 `root.left`
50+
3. 循环以上步骤,直至二叉树节点为空,遍历结束。
51+
4. 最后返回结果列表的逆序即可。
52+
53+
> Morris 后序遍历跟 Morris 前序遍历思路一致,只是将前序的“根左右”变为“根右左”,最后逆序结果即可变成“左右根”。
3654
3755
<!-- tabs:start -->
3856

@@ -51,17 +69,43 @@
5169
# self.right = right
5270
class Solution:
5371
def postorderTraversal(self, root: TreeNode) -> List[int]:
72+
res = []
73+
5474
def postorder(root):
5575
if root:
5676
postorder(root.left)
5777
postorder(root.right)
5878
res.append(root.val)
59-
res = []
79+
6080
postorder(root)
6181
return res
6282
```
6383

64-
非递归:
84+
栈实现非递归:
85+
86+
```python
87+
# Definition for a binary tree node.
88+
# class TreeNode:
89+
# def __init__(self, val=0, left=None, right=None):
90+
# self.val = val
91+
# self.left = left
92+
# self.right = right
93+
class Solution:
94+
def postorderTraversal(self, root: TreeNode) -> List[int]:
95+
res = []
96+
if root:
97+
s = [root]
98+
while s:
99+
node = s.pop()
100+
res.append(node.val)
101+
if node.left:
102+
s.append(node.left)
103+
if node.right:
104+
s.append(node.right)
105+
return res[::-1]
106+
```
107+
108+
Morris 遍历:
65109

66110
```python
67111
# Definition for a binary tree node.
@@ -72,18 +116,23 @@ class Solution:
72116
# self.right = right
73117
class Solution:
74118
def postorderTraversal(self, root: TreeNode) -> List[int]:
75-
if not root:
76-
return []
77-
s1 = [root]
78-
s2 = []
79-
while s1:
80-
node = s1.pop()
81-
s2.append(node.val)
82-
if node.left:
83-
s1.append(node.left)
84-
if node.right:
85-
s1.append(node.right)
86-
return s2[::-1]
119+
res = []
120+
while root:
121+
if root.right is None:
122+
res.append(root.val)
123+
root = root.left
124+
else:
125+
next = root.right
126+
while next.left and next.left != root:
127+
next = next.left
128+
if next.left is None:
129+
res.append(root.val)
130+
next.left = root
131+
root = root.right
132+
else:
133+
next.left = None
134+
root = root.left
135+
return res[::-1]
87136
```
88137

89138
### **Java**
@@ -109,26 +158,63 @@ class Solution:
109158
* }
110159
*/
111160
class Solution {
112-
113-
private List<Integer> res;
114-
115161
public List<Integer> postorderTraversal(TreeNode root) {
116-
res = new ArrayList<>();
117-
postorder(root);
162+
List<Integer> res = new ArrayList<>();
163+
postorder(root, res);
118164
return res;
119165
}
120166

121-
private void postorder(TreeNode root) {
167+
private void postorder(TreeNode root, List<Integer> res) {
122168
if (root != null) {
123-
postorder(root.left);
124-
postorder(root.right);
169+
postorder(root.left, res);
170+
postorder(root.right, res);
125171
res.add(root.val);
126172
}
127173
}
128174
}
129175
```
130176

131-
非递归:
177+
栈实现非递归:
178+
179+
```java
180+
/**
181+
* Definition for a binary tree node.
182+
* public class TreeNode {
183+
* int val;
184+
* TreeNode left;
185+
* TreeNode right;
186+
* TreeNode() {}
187+
* TreeNode(int val) { this.val = val; }
188+
* TreeNode(int val, TreeNode left, TreeNode right) {
189+
* this.val = val;
190+
* this.left = left;
191+
* this.right = right;
192+
* }
193+
* }
194+
*/
195+
class Solution {
196+
public List<Integer> postorderTraversal(TreeNode root) {
197+
LinkedList<Integer> res = new LinkedList<>();
198+
if (root != null) {
199+
Deque<TreeNode> s = new LinkedList<>();
200+
s.offerLast(root);
201+
while (!s.isEmpty()) {
202+
TreeNode node = s.pollLast();
203+
res.addFirst(node.val);
204+
if (node.left != null) {
205+
s.offerLast(node.left);
206+
}
207+
if (node.right != null) {
208+
s.offerLast(node.right);
209+
}
210+
}
211+
}
212+
return res;
213+
}
214+
}
215+
```
216+
217+
Morris 遍历:
132218

133219
```java
134220
/**
@@ -148,25 +234,115 @@ class Solution {
148234
*/
149235
class Solution {
150236
public List<Integer> postorderTraversal(TreeNode root) {
151-
if (root == null) {
152-
return Collections.emptyList();
237+
LinkedList<Integer> res = new LinkedList<>();
238+
while (root != null) {
239+
if (root.right == null) {
240+
res.addFirst(root.val);
241+
root = root.left;
242+
} else {
243+
TreeNode next = root.right;
244+
while (next.left != null && next.left != root) {
245+
next = next.left;
246+
}
247+
if (next.left == null) {
248+
res.addFirst(root.val);
249+
next.left = root;
250+
root = root.right;
251+
} else {
252+
next.left = null;
253+
root = root.left;
254+
}
255+
}
153256
}
154-
Deque<TreeNode> s1 = new ArrayDeque<>();
155-
List<Integer> s2 = new ArrayList<>();
156-
s1.push(root);
157-
while (!s1.isEmpty()) {
158-
TreeNode node = s1.pop();
159-
s2.add(node.val);
160-
if (node.left != null) {
161-
s1.push(node.left);
257+
return res;
258+
}
259+
}
260+
```
261+
262+
### **C++**
263+
264+
```cpp
265+
/**
266+
* Definition for a binary tree node.
267+
* struct TreeNode {
268+
* int val;
269+
* TreeNode *left;
270+
* TreeNode *right;
271+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
272+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
273+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
274+
* };
275+
*/
276+
class Solution {
277+
public:
278+
vector<int> postorderTraversal(TreeNode *root) {
279+
vector<int> res;
280+
while (root)
281+
{
282+
if (root->right == nullptr)
283+
{
284+
res.push_back(root->val);
285+
root = root->left;
162286
}
163-
if (node.right != null) {
164-
s1.push(node.right);
287+
else
288+
{
289+
TreeNode *next = root->right;
290+
while (next->left && next->left != root)
291+
{
292+
next = next->left;
293+
}
294+
if (next->left == nullptr)
295+
{
296+
res.push_back(root->val);
297+
next->left = root;
298+
root = root->right;
299+
}
300+
else
301+
{
302+
next->left = nullptr;
303+
root = root->left;
304+
}
165305
}
166306
}
167-
Collections.reverse(s2);
168-
return s2;
307+
reverse(res.begin(), res.end());
308+
return res;
169309
}
310+
};
311+
```
312+
313+
### **Go**
314+
315+
```go
316+
/**
317+
* Definition for a binary tree node.
318+
* type TreeNode struct {
319+
* Val int
320+
* Left *TreeNode
321+
* Right *TreeNode
322+
* }
323+
*/
324+
func postorderTraversal(root *TreeNode) []int {
325+
var res []int
326+
for root != nil {
327+
if root.Right == nil {
328+
res = append([]int{root.Val}, res...)
329+
root = root.Left
330+
} else {
331+
next := root.Right
332+
for next.Left != nil && next.Left != root {
333+
next = next.Left
334+
}
335+
if next.Left == nil {
336+
res = append([]int{root.Val}, res...)
337+
next.Left = root
338+
root = root.Right
339+
} else {
340+
next.Left = nil
341+
root = root.Left
342+
}
343+
}
344+
}
345+
return res
170346
}
171347
```
172348

0 commit comments

Comments
 (0)