Skip to content

Commit a3712dc

Browse files
committed
144
1 parent 631a948 commit a3712dc

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed

SUMMARY.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
* [98. Validate Binary Search Tree](leetCode-98-Validate-Binary-Search-Tree.md)
103103
* [99. Recover Binary Search Tree](leetcode-99-Recover-Binary-Search-Tree.md)
104104
* [100. Same Tree](leetcode-100-Same-Tree.md)
105-
* [101 题到 143题](leetcode-101-200.md)
105+
* [101 题到 144题](leetcode-101-200.md)
106106
* [101. Symmetric Tree](leetcode-101-Symmetric-Tree.md)
107107
* [102. Binary Tree Level Order Traversal](leetcode-102-Binary-Tree-Level-Order-Traversal.md)
108108
* [103. Binary Tree Zigzag Level Order Traversal](leetcode-103-Binary-Tree-Zigzag-Level-Order-Traversal.md)
@@ -145,4 +145,5 @@
145145
* [140. Word Break II](leetcode-140-Word-BreakII.md)
146146
* [141. Linked List Cycle](leetcode-141-Linked-List-Cycle.md)
147147
* [142. Linked List Cycle II](leetcode-142-Linked-List-CycleII.md)
148-
* [143. Reorder List](leetcode-143-Reorder-List.md)
148+
* [143. Reorder List](leetcode-143-Reorder-List.md)
149+
* [144. Binary Tree Preorder Traversal](leetcode-144-Binary-Tree-Preorder-Traversal.md)

leetcode-101-200.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,6 @@
8282

8383
<a href="leetcode-142-Linked-List-CycleII.html">142. Linked List Cycle II</a>
8484

85-
<a href="leetcode-143-Reorder-List.html">143. Reorder List</a>
85+
<a href="leetcode-143-Reorder-List.html">143. Reorder List</a>
86+
87+
<a href="leetcode-144-Binary-Tree-Preorder-Traversal.html">144. Binary Tree Preorder Traversal</a>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# 题目描述(中等难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/144.jpg)
4+
5+
二叉树的先序遍历。
6+
7+
# 思路分析
8+
9+
之前做过 [94 题](https://leetcode.wang/leetCode-94-Binary-Tree-Inorder-Traversal.html) 的中序遍历,先序遍历的话代码可以直接拿过来用,只需要改一改 `list.add` 的位置。
10+
11+
# 解法一 递归
12+
13+
递归很好理解了,代码也是最简洁的。
14+
15+
```java
16+
public List<Integer> preorderTraversal(TreeNode root) {
17+
List<Integer> list = new ArrayList<>();
18+
preorderTraversalHelper(root, list);
19+
return list;
20+
}
21+
22+
private void preorderTraversalHelper(TreeNode root, List<Integer> list) {
23+
if (root == null) {
24+
return;
25+
}
26+
list.add(root.val);
27+
preorderTraversalHelper(root.left, list);
28+
preorderTraversalHelper(root.right, list);
29+
}
30+
```
31+
32+
# 解法二 栈
33+
34+
第一种思路就是利用栈去模拟上边的递归。
35+
36+
```java
37+
public List<Integer> preorderTraversal(TreeNode root) {
38+
List<Integer> list = new ArrayList<>();
39+
Stack<TreeNode> stack = new Stack<>();
40+
TreeNode cur = root;
41+
while (cur != null || !stack.isEmpty()) {
42+
if (cur != null) {
43+
list.add(cur.val);
44+
stack.push(cur);
45+
cur = cur.left; //考虑左子树
46+
}else {
47+
//节点为空,就出栈
48+
cur = stack.pop();
49+
//考虑右子树
50+
cur = cur.right;
51+
}
52+
}
53+
return list;
54+
}
55+
```
56+
57+
第二种思路的话,我们还可以将左右子树分别压栈,然后每次从栈里取元素。需要注意的是,因为我们应该先访问左子树,而栈的话是先进后出,所以我们压栈先压右子树。
58+
59+
```java
60+
public List<Integer> preorderTraversal(TreeNode root) {
61+
List<Integer> list = new ArrayList<>();
62+
if (root == null) {
63+
return list;
64+
}
65+
Stack<TreeNode> stack = new Stack<>();
66+
stack.push(root);
67+
while (!stack.isEmpty()) {
68+
TreeNode cur = stack.pop();
69+
if (cur == null) {
70+
continue;
71+
}
72+
list.add(cur.val);
73+
stack.push(cur.right);
74+
stack.push(cur.left);
75+
}
76+
return list;
77+
}
78+
```
79+
80+
# 解法三 Morris Traversal
81+
82+
上边的两种解法,空间复杂度都是 `O(n)`,利用 Morris Traversal 可以使得空间复杂度变为 `O(1)`
83+
84+
它的主要思想就是利用叶子节点的左右子树是 `null` ,所以我们可以利用这个空间去存我们需要的节点,详细的可以参考 [94 题](https://leetcode.wang/leetCode-94-Binary-Tree-Inorder-Traversal.html) 中序遍历。
85+
86+
```java
87+
public List<Integer> preorderTraversal(TreeNode root) {
88+
List<Integer> list = new ArrayList<>();
89+
TreeNode cur = root;
90+
while (cur != null) {
91+
//情况 1
92+
if (cur.left == null) {
93+
list.add(cur.val);
94+
cur = cur.right;
95+
} else {
96+
//找左子树最右边的节点
97+
TreeNode pre = cur.left;
98+
while (pre.right != null && pre.right != cur) {
99+
pre = pre.right;
100+
}
101+
//情况 2.1
102+
if (pre.right == null) {
103+
list.add(cur.val);
104+
pre.right = cur;
105+
cur = cur.left;
106+
}
107+
//情况 2.2
108+
if (pre.right == cur) {
109+
pre.right = null; //这里可以恢复为 null
110+
cur = cur.right;
111+
}
112+
}
113+
}
114+
return list;
115+
}
116+
```
117+
118+
#
119+
120+
[94 题](https://leetcode.wang/leetCode-94-Binary-Tree-Inorder-Traversal.html) 没什么差别,解法三利用已有空间去存东西,从而降低空间复杂度的思想经常用到。

0 commit comments

Comments
 (0)