二叉树的前序遍历
144. 二叉树的前序遍历
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点数目在范围
[0, 100]
内 -100 <= Node.val <= 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?
动态规划,后序归并
每层递归都新建一个res,用于存储以本节点为根节点的二叉树的前序遍历的结果。
先把根节点放入链表,再把左右子树的前序遍历结果加入链表。没有承上,只有启下。
递归的返回值是以本节点为根节点的树的前序遍历的结果。结束条件是遇到null
动态规划有返回值,会利用子递归的返回值来构建父递归的返回值
class Solution {
// 定义:输入一个节点,返回以该节点为根的二叉树的前序遍历结果
public List<Integer> preorderTraversal(TreeNode root) {
// 每次都会定义一个res。重点。
List<Integer> res = new LinkedList<>();
// 特殊条件和前进结束条件
if (root == null) {
return res;
}
// 前序遍历结果特点:第一个是根节点的值,接着是左子树,最后是右子树
res.add(root.val);
res.addAll(preorderTraversal(root.left));
res.addAll(preorderTraversal(root.right));
return res;
}
}
时间复杂度O(n),即遍历整棵二叉树。空间复杂度O(h),h是树的高度。
回溯,无返回值无信息参数的DFS+全局变量。
对每层递归,先添加节点,再进入左右子递归。
回溯没有返回值,直接在递归内部操作完了。和动态规划的区别不大
class Solution {
List<Integer> res = new LinkedList<>();
// 返回前序遍历结果
public List<Integer> preorderTraversal(TreeNode root) {
traverse(root);
return res;
}
// 二叉树遍历函数
void traverse(TreeNode root) {
if (root == null) {
return;
}
// 前序遍历位置
res.add(root.val);
traverse(root.left);
traverse(root.right);
}
}