【算法-LeetCode】257. 二叉树的所有路径(二叉树;递归;DFS;前序遍历;BFS)

257. 二叉树的所有路径 - 力扣(LeetCode)

文章起笔:2021年11月13日22:22:02

问题描述及示例

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例 1:
【算法-LeetCode】257. 二叉树的所有路径(二叉树;递归;DFS;前序遍历;BFS)_第1张图片
输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]

示例 2:
输入:root = [1]
输出:[“1”]

注意:
树中节点的数目在范围 [1, 100] 内
-100 <= Node.val <= 100

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的题解

我的题解1(DFS;前序遍历)

之前做过一道题目:

参考:【算法-LeetCode】129. 求根节点到叶节点数字之和(递归;回溯)_赖念安的博客-CSDN博客

虽然上面这道题和本题要解决的问题不一样,但是解决问题的原理都是一样的。上面那道题其实也是先要求二叉树的所有路径。

所以,在上面那道题的基础上,我做了一些改进和增减操作,写出了下面的这种DFS解法:

/**
 * 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 {string[]}
 */
var binaryTreePaths = function (root) {
  // paths用于存储所有找到的路径
  let paths = [];
  dfs(root, []);
  return paths;

  // dfs用于获取以node为根节点的树的所有路径,
  // 其中,path用于存储某一条路径,其初始值为一个空数组
  function dfs(node, path) {
    // 如果当前节点为空节点,则用return语句结束当前层的递归
    if (!node) {
      return;
    }
    // 否则的话就在path数组中存入当前遍历的节点的节点值
    path.push(node.val);
    // 如果当前节点为叶子节点
    if (!node.left && !node.right) {
      // 说明找到了一条完整路径,此时将path中存储的完整路径用 -> 拼接起来并压入paths中
      paths.push(path.join('->'));
    }
    // 然后继续向下遍历,注意,此处使用了扩展运算符将目前找到的路径作为参数传递给了下一层
    // 这里的传参操作是整个函数的核心
    dfs(node.left, [...path]);
    dfs(node.right, [...path]);
  }
};


提交记录
执行结果:通过
208 / 208 个通过测试用例
执行用时:72 ms, 在所有 JavaScript 提交中击败了73.25%的用户
内存消耗:39 MB, 在所有 JavaScript 提交中击败了94.85%的用户
时间:2021/11/13 22:25

我的题解2(BFS)

其实,这种找路径的题目用DFS来做会比较合适,因为寻找一条路径的过程就是一个深度优先搜索的过程。

但是其实也可以使用BFS的思路,因为说到底,本题还是在遍历一棵二叉树嘛,而我们使用BFS其实也是可以达到遍历的目的的。有关BFS遍历的描述,详细可参看下方链接:

参考:【算法-LeetCode】102. 二叉树的层序遍历(二叉树;层序遍历;BFS;生成二叉树)_赖念安的博客-CSDN博客

本题中运用到的基本思路和上面的这个博客里的思路是一样的。唯一需要特别注意的就是,我们不是单纯地利用某一层的遍历结果,而是把上一层的遍历结果也保留到当前层中,这种保存之前遍历结果的操作就像是上面的DFS中关键的那个向下一层递归传参的操作一样。

var binaryTreePaths = function (root) {
  let paths = [];
  // pathQueue是一个用于保存路径的队列,在形式上是一个二维数组,
  // 其中的每一个元素都是一条路径,但是注意该路径并不一定都完整(即并不一定都包含叶子节点)
  // 理解这点是非常关键的,因为下面针对这个队列的操作的原由就是由此推出的
  let pathQueue = [];
  // 注意pathQueue的初始值是一条包含根节点的路径
  pathQueue.push([root.val]);
  // nodeQueue用于存储遍历过程中的节点,这点和普通的层序遍历中借助的队列结构一样
  let nodeQueue = [root];

  // 下面层序遍历的逻辑和普通的层序遍历是一样的,该注意的点也在上面的博客中提到了
  // 关键是要关注我们对pathQueue这个队列的操作,其实一开始,我们对pathQueue的操作
  // 大体上和对nodeQueue的操作是一样的
  while (nodeQueue.length) {
    for (let i = 0, len = nodeQueue.length; i < len; i++) {
      let node = nodeQueue.shift();
      let path = pathQueue.shift();
      // 如果当前节点是叶子节点,则说明找到一条完整的路径path,需要将其存入paths中
      if (!node.left && !node.right) {
        paths.push(path.join('->'));
        continue;
      }
      
      // 如果当前节点的左子节点不为空
      if (node.left) {
        // 则将其压入nodeQueue队列,这里和普通的层序遍历是一样的
        nodeQueue.push(node.left);
        // 接下来的操作就和普通的层序遍历有点不一样了
        // 拷贝一份path的值并用 temp 变量接收,因为path是数组对象,
        // 所以不能简单地写成 temp = path,否则会影响后续操作
        let temp = [...path];
        // 往temp路径中压入当前节点的左子节点的节点值
        temp.push(node.left.val);
        // 并将temp路径保存进pathQueue中,经过这三步操作,就能保存此前的遍历结果了
        pathQueue.push([...temp]);
      }
      // 下面也是和上面同理
      if (node.right) {
        nodeQueue.push(node.right);
        let temp = [...path];
        temp.push(node.right.val);
        pathQueue.push([...temp]);
      }
    }
  }
  // 最后返回paths
  return paths;
};


提交记录
执行结果:通过
208 / 208 个通过测试用例
执行用时:80 ms, 在所有 JavaScript 提交中击败了32.59%的用户
内存消耗:39.2 MB, 在所有 JavaScript 提交中击败了71.48%的用户
时间:2021/11/13 23:27

【算法-LeetCode】257. 二叉树的所有路径(二叉树;递归;DFS;前序遍历;BFS)_第2张图片

pathQueue中的元素会保存相应的路径

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

【更新结束】

更新:2021年11月13日22:26:33

参考:二叉树的所有路径 - 二叉树的所有路径 - 力扣(LeetCode)

【更新结束】

有关参考

更新:2021年11月13日22:27:47
参考:【算法-LeetCode】129. 求根节点到叶节点数字之和(递归;回溯)_赖念安的博客-CSDN博客
更新:2021年11月13日23:31:37
参考:【算法-LeetCode】102. 二叉树的层序遍历(二叉树;层序遍历;BFS;生成二叉树)_赖念安的博客-CSDN博客

你可能感兴趣的:(LeetCode,算法,二叉树,bfs,dfs,javascript)