[路飞]_LeetCode_662. 二叉树最大宽度

91 阅读2分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战

题目

给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空。

每一层的宽度被定义为两个端点(该层最左和最右的非空节点,两端点间的null节点也计入长度)之间的长度。

示例 1:

输入:

       1
     /   \
    3     2
   / \     \  
  5   3     9 

输出: 4 解释: 最大值出现在树的第 3 层,宽度为 4 (5,3,null,9)。 示例 2:

输入:

      1
     /  
    3    
   / \       
  5   3     

输出: 2 解释: 最大值出现在树的第 3 层,宽度为 2 (5,3)。 示例 3:

输入:

      1
     / \
    3   2 
   /        
  5      

输出: 2 解释: 最大值出现在树的第 2 层,宽度为 2 (3,2)。 示例 4:

输入:

      1
     / \
    3   2
   /     \  
  5       9 
 /         \
6           7

输出: 8 解释: 最大值出现在树的第 4 层,宽度为 8 (6,null,null,null,null,null,null,7)。 注意: 答案在32位有符号整数的表示范围内。

来源:力扣(LeetCode)leetcode-cn.com/problems/ma…

解题思路

  • 定义新的数据结构:{ node: root, ind: 0 }
  • 计算出每个节点在当层的索引;
    • 左子节点索引 = 根节点索引 * 2
    • 右子节点索引 = 根节点索引 * 2 + 1
  • 每层的宽度 = 最右节点索引 - 最左节点索引 + 1;
  • 比较每层的宽度,得到最大宽度;

代码实现

var widthOfBinaryTree = function (root) {
    //定义新的数据结构 { node: root, ind: 0 }
    //计算出每个节点在当层的索引
    const queue = [{node: root, ind: 0 }]
    let ans = 0

    while (queue.length > 0) {
        const len = queue.length
        //保存当层最左索引和最右索引
        let l = r = queue[0].ind
        
        for (let i = 0; i < len; i++) {
            const { node, ind } = queue.shift()
            r = ind
            
            //计算左节点索引,左子节点索引等于当前节点乘2
            if (node.left) queue.push({
                node: node.left,
                ind: 2 * (ind - l)
            })
            
            //计算右节点索引,右子节点索引等于当前节点乘2加1
            if (node.right) queue.push({
                node: node.right,
                ind: 2 * (ind - l) + 1
            })
        }

        //最右一个节点的索引减左索引加1得到本层宽度,并更新最大宽度
        ans = Math.max(ans, r - l + 1)
    }

    return ans
};

如有错误欢迎指出,欢迎一起讨论!