[层序遍历、深度优先遍历] 515. 在每个树行中找最大值

75 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

每日刷题 2022.06.24

题目

  • 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。

示例

  • 示例1 image.png
输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
  • 示例2
输入: root = [1,2,3]
输出: [1,3]

提示

  • 二叉树的节点个数的范围是 [0,10^4]
  • -2^31 <= Node.val <= 2^31 - 1

解题思路

  • 针对图的操作:层序遍历、前中后序遍历、深度遍历
  • 分析题意可知:需要找出二叉树中每一层的最大值。提取关键字:每层、最大值
  • 那么使用层序遍历就可以解决,因为层序遍历是借助队列对二叉树的每一层进行遍历,那么只要在每一层中找到最大值进行存储就可以了。

方法1:层序遍历bfs

  • 层序遍历,就是常规的bfs板子题,使用队列记录每一层的节点,从每一层的节点中找到最大值,存储在数组ans中。

方法2:深度遍历dfs

  • 深度优先遍历也是可以解决本题的,因为在遍历的时候,带上每一个节点的深度就可以了。
  • 因为深度并不是每次先处理每一层,而是先处理从根到最下面的节点,也就是说处于同一层的节点,会被分散开遍历到,那么我们就需要存储每一层的值,以便后续再遍历到这一层的时候,取出来和当前的值进行比较,取最大值再放入到这一层。

注意

  • 使用深度遍历的时候,需要使用map来映射关系。
  • 本题的数据范围是从负数到正数的,那么map.set(depth, Math.max((map.get(depth) || -Infinity), node.val)就会出错。因为这样写的map是用来计数的,而不是用来存储数值的。
  • 仔细分析:(map.get(depth) || -Infinity), 当前面的节点值为0的时候,就会出现短路的问题,那么就会直接取-Infinity,这样就会丢失掉0这个节点值。

AC代码

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var largestValues = function(root) {
  // dfs使用深度变量
  let ans = [];
  if(root == null) return ans;
  let map = new Map(), maxDepth = 0;
  function dfs(node, depth) {
    if(node == null){
      // console.log(depth)
      maxDepth = Math.max(depth - 1, maxDepth);
      return;
    }
    if(map.has(depth)) {
      map.set(depth, Math.max(map.get(depth), node.val))
    }else {
      map.set(depth, node.val)
    }
    // console.log('depth:::', map.get(depth), depth)
    dfs(node.left, depth + 1);
    dfs(node.right, depth + 1);
  }
  dfs(root, 1);
  // console.log(map, maxDepth)
  ans = new Array(maxDepth).fill(0);
  map.forEach((value, key) => {
    ans[key - 1] = value;
  });
  return ans;
};