[LeetCode] 问题系列 - Binary Tree Tr
2020-06-07 本文已影响0人
YoungJadeStone
从大的层面讲,Binary Tree 可以用DFS和BFS。
- 对于BFS,我们需要 iterative with queue。
- 对于DFS,Binary Tree 有三种traversal的方式:
** Inorder Traversal: left -> root -> right
** Preoder Traversal: root -> left -> right
** Postoder Traveral: left -> right -> root
记忆方式:order的名字指的是root在什么位置。left,right的相对位置是固定的。

对于时间复杂度来说,基本上都是O(n),因为要访问所有的点。
对于空间复杂度来说,BFS取决于扫描过程中每层的node数,就是树的宽度,而DFS取决于扫描过程中树的深度。最坏情况两个都是O(n)。
本文重点讨论iterative和recursive方法。对于morris,另开一篇介绍。
Inorder Traversal
首先是recursion写法,相对简单:
// left->root->right
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
res.addAll(inorderTraversal(root.left));
res.add(root.val);
res.addAll(inorderTraversal(root.left));
}
如果用iteration:
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) { // 把左路径上遇到的点都放进stack里面
stack.push(cur);
cur = cur.left;
} // while循环结束的时候,cur==null
cur = stack.pop();
res.add(cur.val);
cur = cur.right;
}
return res;
}
Preorder Traversal
首先是recursion写法,相对简单:
// root->left->right
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
res.add(root.val);
res.addAll(inorderTraversal(root.left));
res.addAll(inorderTraversal(root.left));
}
如果用iteration:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
TreeNode cur = root;
while (!stack.isEmpty()) {
cur = stack.pop();
res.add(cur.val);
if (cur.right != null) {
stack.push(cur.right);
}
if (cur.left != null) {
stack.push(cur.left);
}
}
return res;
}
Postorder Traversal
首先是recursion写法,相对简单:
// left->right->root
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) {
return res;
}
res.addAll(inorderTraversal(root.left));
res.addAll(inorderTraversal(root.left));
res.add(root.val);
}
如果用iteration:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList<>(); // 便于Insert操作
if (root == null) {
return res;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
res.add(0, node.val); // 因为这一步,所以转变成了root->right->left
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
return res;
}