【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语言版

相关推荐
全栈技术负责人11 分钟前
DeepSeek Harness 业务工具权限插件 dsh-tool-permission设计思路
网络·算法·ai·ai编程
mmmmath_316 分钟前
面试题 02.07. 链表相交
算法·链表
圣保罗的大教堂28 分钟前
leetcode 3903. 最小稳定下标 I 简单
leetcode
residual_fan1 小时前
特征级SMOTE(Feature-level SMOTE)论文分享
人工智能·算法·数据挖掘·数据分析
xxwxx__1 小时前
深入理解 C++ STL:stack、queue 与 deque 从使用到底层实现全解析
开发语言·c++·算法
sylviiiiiia1 小时前
Leetcode hot100 多数元素/相交链表/反转链表
算法·leetcode·链表
CoderYanger1 小时前
A.每日一题:3622. 判断整除性
java·程序人生·算法·leetcode·面试·职场和发展·蓝桥杯
rannn_1111 小时前
【力扣hot100】动态规划专题|70、118、198、279、322、139、300、152、416、32
算法·leetcode·动态规划
渡之1 小时前
ArduPilot(APM)滤波器之 HarmonicNotchFilter 深度解析
算法·无人机
我不会起名字3221 小时前
一天一道算法题(26):栈的简单应用
java·数据结构·python·算法·leetcode·golang·