LeetCode系列记录我学习算法的过程。
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情
题目
给你二叉树的根节点 root ,返回它节点值的 前序 **遍历。
示例:
输入: root = [1,null,2,3]
输出: [1,2,3]
输入: root = [1,2]
输出: [1,2]
提示:
- 树中节点数目在范围
[0, 100]内 -100 <= Node.val <= 100
思路
二叉树常见的三种遍历方式分别是先序、中序和后序遍历,先序遍历的特点就是先遍历根结点的值,再遍历左子树,最后右子树
例如上图,先序遍历得到的结果是: 1 2 4 6 7 8 3 5
知道规律后就不难解决了,也是用递归的方式来实现:
- 首先判断根结点是否存在,不存在则直接返回空数组
- 根结点存在则定义一个数组存储结果,将根结点值存入其中
- 然后判断左子树是否存在,存在则递归左子树
- 将左子树递归后的结果与初始结果合并
- 然后判断右子树是否存在,存在则递归右子树
- 将递归后的结果与之前的结果合并
- 最后将结果返回即可
代码实现
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var preorderTraversal = function(root) {
// 如果当前根结点不存在,返回空数组
if (!root) return []
// 根结点存在则将其值存入数组
let arr = [root.val]
// 如果左子树存在,则递归左子树,将结果与递归后的值合并
if (root.left) {
arr = [...arr, ...preorderTraversal(root.left)]
}
// 右子树存在同上操作
if (root.right) {
arr = [...arr, ...preorderTraversal(root.right)]
}
// 最后返回结果
return arr
};
优化
递归是最简单的实现方式,这个题目还可以用栈和迭代的方式来实现
var preorderTraversal = function(root, res = []) {
const stack = [];
if (root) stack.push(root);
while(stack.length) {
const node = stack.pop();
if(!node) {
res.push(stack.pop().val);
continue;
}
if (node.right) stack.push(node.right); // 右
if (node.left) stack.push(node.left); // 左
stack.push(node); // 中
stack.push(null);
};
return res;
};