【LeetCode每日一题】——662.二叉树最大宽度

文章目录

一【题目类别】

  • 广度优先搜索

二【题目难度】

  • 中等

三【题目编号】

  • 662.二叉树最大宽度

四【题目描述】

  • 给你一棵二叉树的根节点 root ,返回树的 最大宽度
  • 树的 最大宽度 是所有层中最大的 宽度
  • 每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度。
  • 题目数据保证答案将会在 32 位 带符号整数范围内。

五【题目示例】

  • 示例 1:

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

    • 输入:root = 1,3,2,5,null,null,9,6,null,7
    • 输出:7
    • 解释:最大宽度出现在树的第 4 层,宽度为 7 (6,null,null,null,null,null,7) 。
  • 示例 3:

    • 输入:root = 1,3,2,5
    • 输出:2
    • 解释:最大宽度出现在树的第 2 层,宽度为 2 (3,2) 。

六【题目提示】

  • 树中节点的数目范围是 [1, 3000]
  • 100 <= Node.val <= 100

七【解题思路】

  • 其实这道题就是二叉树的层序遍历的变种
  • 值得注意的是需要利用完全二叉树的性质
    • 在完全二叉树中,可以将其节点存储到数组中,并且对于序号为i的节点(节点编号从1开始),其
      • 左子节点的序号为i * 2
      • 右子节点的序号为i * 2 + 1
    • 利用以上性质,我们可以将每一层的二叉树的节点编号,用编号值计算每一层的宽度
    • 当计算出每一层的宽度 后,就可以计算得到整个二叉树的最大宽度
  • 具体细节请参考下面的代码

八【时间频度】

  • 时间复杂度: O ( n ) O(n) O(n), n n n为传入的二叉树的节点个数
  • 空间复杂度: O ( n ) O(n) O(n), n n n为传入的二叉树的节点个数

九【代码实现】

  1. Java语言版
java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */

class Solution {
    public int widthOfBinaryTree(TreeNode root) {
        // 最小宽度为1
        int res = 1;

        // 初始化队列,queue用于存储当前层节点
        List<Pair<TreeNode, Integer>> queue = new ArrayList<Pair<TreeNode, Integer>>();
        queue.add(new Pair<TreeNode, Integer>(root, 1));

        // 使用广度优先遍历算法计算二叉树的最大高度
        while (!queue.isEmpty()) {

            // temp用于存储下一层节点
            List<Pair<TreeNode, Integer>> temp = new ArrayList<Pair<TreeNode, Integer>>();

            for (Pair<TreeNode, Integer> pair : queue) {
                TreeNode node = pair.getKey();
                int index = pair.getValue();
                if (node.left != null) {
                    temp.add(new Pair<TreeNode, Integer>(node.left, index * 2));
                }
                if (node.right != null) {
                    temp.add(new Pair<TreeNode, Integer>(node.right, index * 2 + 1));
                }
            }

            // 计算二叉树的最大宽度
            res = Math.max(res, queue.get(queue.size() - 1).getValue() - queue.get(0).getValue() + 1);
            queue = temp;
        }

        // 返回结果
        return res;
    }
}
  1. Python语言版
python 复制代码
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def widthOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        # 最小宽度为1
        res = 1
        
        # 初始化队列,queue用于存储当前层节点
        queue = [[root, 1]]

        # 使用广度优先遍历算法计算二叉树的最大高度
        while queue:

            # temp用于存储下一层节点
            temp = []

            for node, index in queue:
                if node.left:
                    temp.append([node.left, index * 2])
                if node.right:
                    temp.append([node.right, index * 2 + 1])
            
            # 计算二叉树的最大宽度
            res = max(res, queue[-1][1] - queue[0][1] + 1)
            queue = temp

        # 返回结果
        return res
  1. C语言版
c 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

// 节点最多3000个
#define MAX_NODE_SIZE 3000

// 比较大小
#define MAX(a, b) ((a) > (b) ? (a) : (b));

// 利用完全二叉树的性质存储二叉树,node保留了节点的左右子树的关系,index记录节点(在数组中)的位置(索引)
typedef struct
{
    struct TreeNode* node;
    unsigned long long index;
} levelNode;

int widthOfBinaryTree(struct TreeNode* root)
{
    // 最小宽度为1
    unsigned long long res = 1;

    // 初始化队列,queue用于存储当前层节点,temp用于存储下一层节点
    levelNode* queue = (levelNode*)malloc(sizeof(levelNode) * MAX_NODE_SIZE);
    levelNode* temp = (levelNode*)malloc(sizeof(levelNode) * MAX_NODE_SIZE);
    int queueSize = 0;
    int tempSize = 0;
    
    // 根节点入队列
    queue[queueSize].node = root;
    queue[queueSize++].index = 1LL;

    // 使用广度优先遍历算法计算二叉树的最大宽度
    while (queueSize > 0)
    {
        // 将当前节点的所有下一层节点按照完全二叉树的索引值存储
        tempSize = 0;
        for (int i = 0; i < queueSize; i++)
        {
            if (queue[i].node->left)
            {
                temp[tempSize].node = queue[i].node->left;
                temp[tempSize++].index = queue[i].index * 2;
            }
            if (queue[i].node->right)
            {
                temp[tempSize].node = queue[i].node->right;
                temp[tempSize++].index = queue[i].index * 2 + 1;
            } 
        }
        // 计算二叉树的最大宽度
        res = MAX(res, queue[queueSize - 1].index - queue[0].index + 1);
        
        // 将存储当前层节点信息的队列重新赋值为存储好的下一层节点的信息队列
        queueSize = tempSize;
        levelNode* change = queue;
        queue = temp;
        temp = change;
    }
    // 返回结果
    return res;
}

十【提交结果】

  1. Java语言版

  2. Python语言版

  3. C语言版

相关推荐
wabs6667 小时前
关于贪心算法的思考
算法·贪心算法
社交怪人7 小时前
【判断大小】信息学奥赛一本通C语言解法(题号1043)
算法
Snasph8 小时前
GNU Make 用户手册(中文版)
服务器·算法·gnu
江澎涌8 小时前
拆解与 AI 的一次对话
人工智能·算法·程序员
sheeta19988 小时前
LeetCode 每日一题笔记 日期:2026.06.02 题目:3635. 最早完成陆地和水上游乐设施的时间 II
笔记·算法·leetcode
Lsk_Smion9 小时前
力扣实训 _ [102].层序遍历--前序--后续_递归与非递归的实现
数据结构·算法·leetcode
Lsk_Smion9 小时前
力扣实训 _ [25].K个一组链表
数据结构·链表
小欣加油10 小时前
leetcode3751 范围内总波动值I
java·数据结构·c++·算法·leetcode
Halo_tjn11 小时前
反射与设计模式1
java·开发语言·算法
V搜xhliang024612 小时前
临床科研新范式:从选题到投稿,AI智能体如何接管全流程?
运维·数据结构·人工智能·算法·microsoft·数据挖掘·自动化