一、需求
- 给你二叉树的根节点
root
,返回它节点值的 前序 遍历。
输入:root = [1,null,2,3] 输出:[1,2,3]
提示:
- 树中节点数目在范围
[0, 100]
内-100 <= Node.val <= 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?
二、递归法
2.1 思路分析
- 按照根、左、右的顺序递归子树即可;
2.2 代码实现
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
preOrder(root);
return res;
}
private void preOrder(TreeNode root) {
if(root == null) {
return;
}
res.add(root.val);
preOrder(root.left);
preOrder(root.right);
}
}
2.3 复杂度分析
- 时间复杂度为O(N),其中N为二叉树节点的个数;
- 空间复杂度为O(N),最坏情况下,二叉树退化为链表,递归的深度可达N;
三、迭代法
3.1 思路分析
- 想想二叉树的前序遍历,按照根、左、右的方式进行,现在要显式的模拟递归时的入栈过程,首先是根节点,然后是其左子树,最后是右子树;
- 然后发现代码2中的一部分代码是可以省略的;
3.2 代码实现
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
if(root == null) {
return res;
}
res.add(root.val);
stack.push(root);
TreeNode node = root.left;
//node != null作用是当栈中的根节点弹出时,此时栈为空,node指向右子节点
while(node != null || !stack.isEmpty()) {
while(node != null) {
res.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
}
3.3 代码优化
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode node = root;
//node != null作用是当栈中的根节点弹出时,此时栈为空,node指向右子节点
while(node != null || !stack.isEmpty()) {
while(node != null) {
res.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
}
3.4 复杂度分析
- 时间复杂度为O(N),需要遍历所有的节点;
- 空间复杂度为O(N),最坏情况下,二叉树退化为链表,消耗O(N)的额外空间;
四、学习地址
作者:LeetCode-Solution