11# Binary Tree Preorder Traversal
22
3+ Tags: Tree, Stack, Medium
4+
35## Question
46
5- - leetcode: [ Binary Tree Preorder Traversal | LeetCode OJ ] ( https://leetcode.com/problems/binary-tree-preorder-traversal/ )
6- - lintcode: [ (66) Binary Tree Preorder Traversal] ( http://www.lintcode.com/en/problem/binary-tree-preorder-traversal/ )
7+ - leetcode: [ Binary Tree Preorder Traversal] ( https://leetcode.com/problems/binary-tree-preorder-traversal/ )
8+ - lintcode: [ Binary Tree Preorder Traversal] ( http://www.lintcode.com/en/problem/binary-tree-preorder-traversal/ )
79
810### Problem Statement
911
10- Given a binary tree, return the preorder traversal of its nodes' values.
11-
12- #### Example
12+ Given a binary tree, return the _ preorder_ traversal of its nodes' values.
1313
14- Given binary tree ` {1,#,2,3} ` :
14+ For example:
15+ Given binary tree ` {1,#,2,3} ` ,
1516
1617
1718
18- 1
19- \
20- 2
21- /
22- 3
19+
20+ 1
21+ \
22+ 2
23+ /
24+ 3
2325
2426
2527return ` [1,2,3] ` .
2628
27- #### Challenge
28-
29- Can you do it without recursion?
29+ ** Note:** Recursive solution is trivial, could you do it iteratively?
3030
3131## 题解1 - 递归
3232
@@ -83,7 +83,7 @@ public:
8383 vector<int > preorderTraversal(TreeNode * root) {
8484 vector<int > result;
8585 if (root != NULL) {
86- // Divide (分)
86+ // Divide
8787 vector<int > left = preorderTraversal(root->left);
8888 vector<int > right = preorderTraversal(root->right);
8989 // Merge
@@ -167,16 +167,43 @@ public class Solution {
167167}
168168```
169169
170+ ### Java - Traversal
171+
172+ ```
173+ /**
174+ * Definition for a binary tree node.
175+ * public class TreeNode {
176+ * int val;
177+ * TreeNode left;
178+ * TreeNode right;
179+ * TreeNode(int x) { val = x; }
180+ * }
181+ */
182+ public class Solution {
183+ private List<Integer> result = new ArrayList<Integer>();
184+
185+ public List<Integer> preorderTraversal(TreeNode root) {
186+ if (root != null) {
187+ result.add(root.val);
188+ preorderTraversal(root.left);
189+ preorderTraversal(root.right);
190+ }
191+
192+ return result;
193+ }
194+ }
195+ ```
196+
170197### 源码分析
171198
172- 使用遍历的方法保存递归返回结果需要使用辅助递归函数` traverse ` ,将结果作为参数传入递归函数中,传值时注意应使用` vector ` 的引用。
199+ 使用遍历的方法保存递归返回结果需要使用辅助递归函数` traverse ` ,将结果作为参数传入递归函数中,传值时注意应使用` vector ` 的引用。另外一个方法则是使用类的私有变量保存最终结果。
173200分治方法首先分开计算各结果,最后合并到最终结果中。
174201C++ 中由于是使用vector, 将新的vector插入另一vector不能再使用push_back, 而应该使用insert。
175202Java 中使用` addAll ` 方法.
176203
177204### 复杂度分析
178205
179- 遍历树中节点,时间复杂度 $$ O(n) $$ , 未使用额外空间。
206+ 遍历树中节点,时间复杂度 $$ O(n) $$ , 遍历的方法未使用额外空间,分治的方法生成了临时变量,最差情况下空间复杂度为 $$ (n) $$ .
180207
181208## 题解2 - 迭代
182209
@@ -274,18 +301,16 @@ public:
274301public class Solution {
275302 public List<Integer > preorderTraversal (TreeNode root ) {
276303 List<Integer > result = new ArrayList<Integer > ();
277- if (root == null ) return result;
278-
304+
279305 Deque<TreeNode > stack = new ArrayDeque<TreeNode > ();
280- stack. push(root);
306+ if (root != null ) stack. push(root);
281307 while (! stack. isEmpty()) {
282- TreeNode node = stack. pop();
283- result. add(node. val);
284-
285- if (node. right != null ) stack. push(node. right);
286- if (node. left != null ) stack. push(node. left);
308+ root = stack. pop();
309+ result. add(root. val);
310+ if (root. right != null ) stack. push(root. right);
311+ if (root. left != null ) stack. push(root. left);
287312 }
288-
313+
289314 return result;
290315 }
291316}
@@ -306,4 +331,4 @@ public class Solution {
306331
307332### 复杂度分析
308333
309- 使用辅助栈,最坏情况下栈空间与节点数相等,空间复杂度近似为 $$ O(n) $$ , 对每个节点遍历一次,时间复杂度近似为 $$ O(n) $$ .
334+ 使用辅助栈,最坏情况下栈空间与节点数相等,其空间复杂度为 $$ O(n) $$ , 对每个节点遍历一次,时间复杂度为 $$ O(n) $$ .
0 commit comments