二叉树的深度问题

79 阅读2分钟

题目(104):求解二叉树的最大深度

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。

示例:

给定二叉树 [3,9,20,null,null,15,7],

  3
 / \
9  20
  /  \
 15   7

返回它的最大深度 3。

提示:节点总数 <= 10000

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

解答

思路

  • 遍历二叉树,在遍历的过程中记录遍历到的节点所在的层级
  • 当到达叶子节点时,将此时的层级与最大深度两者取最大值重新赋值给最大深度
  • 遍历结束后,返回最大深度

递归版深度优先遍历

深度优先遍历是求解深度问题的优先方案,递归的方式是最常见的方法。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
  let res = 0;
  const dfs = (node, level) => {
    if (!node) {return;}
    if (!node.left && !node.right) {
      // 叶子节点处再更新res
      res = Math.max(res, level)
    }
    if (node.left) {
      dfs(node.left, level + 1)
    }
    if (node.right) {
      dfs(node.right, level + 1)
    }
  }
  dfs(root, 1);
  return res;
};

非递归版 前序遍历

由于递归调用栈涉及到递归深度,高级语言的执行引擎对递归深度的支持不同,例如JavaScript执行引擎通常支持10000以内的递归深度,因此涉及到树如果深度比较大的情况下,使用递归的方法就会出错。这里采用非递归的方式来实现。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
  // 前序遍历非递归版本
  if (!root) return 0;
  let res = 1;
  const stack = [];
  // 每次入栈时,除了将节点入栈,还需要保存节点的层级
  stack.push([root, 1]);
  while (stack.length > 0) {
    let [node, level] = stack.pop();
    if (!node.left && !node.right) {
      // 叶子节点,更新深度
      res = Math.max(res, level);
    }
    if (node.right) {
      stack.push([node.right, level + 1]);
    }
    if (node.left) {
      stack.push([node.left, level + 1]);
    }
  }
  return res;
};

题目(111)

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

示例 1:

image.png

输入:root = [3,9,20,null,null,15,7]

输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]

输出:5

提示:

树中节点数的范围在 [0, 10^5]

-1000 <= Node.val <= 1000

解答

最小深度的问题使用广度优先遍历最合适,一旦遍历到叶子节点即可返回其所在层级。

广度优先遍历

/**
 * 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 minDepth = function(root) {
  if (!root) {return 0;}
    const queue = [];
    queue.push([root, 1]);
    while (queue.length > 0) {
      const [n, level] = queue.shift();
      if (!n.left && !n.right) {
        return level;
      }
      if (n.left) {
        queue.push([n.left, level + 1])
      }
      if (n.right) {
        queue.push([n.right, level + 1]);
      }
    }
};