LeetCode 144. Binary Tree Preorder Traversal
2020-05-17 11:02:57 # leetcode

Problem

LeetCode 144. Binary Tree Preorder Traversal

1. 题目简述:

给出一颗二叉树,返回其前序遍历的顺序(List形式),且尽量使用非递归的形式。例如:

Input: [1,null,2,3]
1
 \
  2
 /
3
Output: [1,2,3]  

2. 算法思路

Stack:

递归的形式很好写,普通的前序遍历,这里不再赘述。问题在于非递归(迭代)的形式怎么办。

我们都知道递归其实就是计算完某节点后不断返回上一级的方法,如果用递归达到同样效果,一般都需要使用栈Stack!

遍历过程:

  1. 如果节点不为空,访问某节点。
  2. 如果某节点存在右子树,压栈;如果存在左子树,压栈(这样弹出时是先左后右)。

Condition Statement:

  1. 注意,第一种解法中这里要先把root给压栈。
  2. 第一种解法中,要注意root为null的情况,所以while判断条件中加了node != null的条件,否则会出现NullPointerException。
  3. 第二种解法中,压栈的目的只是为了回溯找右节点,而不是弹出时访问。第一种解法更清晰,是弹出时访问。二者思路有很大不同。

3. 解法

这里提供两种遍历思路:

  1. 遍历时先压右子树,再压左子树。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
List<Integer> list = new ArrayList<Integer>();
TreeNode node = root;
stack.push(node);

while (!stack.isEmpty() && node != null) {
node = stack.pop();
list.add(node.val);
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}

return list;
}
}
  1. 压栈的目的只是为了回溯找右节点,不是压左右子树,而是访问过的节点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
List<Integer> list = new ArrayList<Integer>();
TreeNode node = root;

while (!stack.isEmpty() || node != null) {
if (node != null) {
list.add(node.val);
stack.push(node);
node = node.left;
} else {
node = stack.pop().right;
}
}

return list;
}
}