662. 二叉树最大宽度(中)
题目
-
给你一棵二叉树的根节点 root ,返回树的 最大宽度 。
树的 最大宽度 是所有层中最大的 宽度 。
每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点, 这些 null 节点也计入长度。
题目数据保证答案将会在 32 位 带符号整数范围内。
题解:BFS
- 从根节点开始,逐层遍历每个节点。对于每个节点,如果其左子节点存在,则将左子节点加入队列;如果左子节点不存在,则创建一个值为0的新节点,并将其作为当前节点的左子节点添加到二叉树中。同样地处理右子树。然后,记录每一层的节点个数,更新最大宽度 m 的值为当前层的节点个数 size 和 m 中的较大值。最终返回最大宽度 m。
class Solution:
def widthOfBinaryTree(self, root: Optional[TreeNode]) -> int:
#如果谁的孩子是空就给创一个值为0的结点,用BFS计算每一层多少个结点,返回最大那个
if not root:
return 0
q=[root]
m=0# 最大宽度
while q:
size=len(q)
m=max(m,size)# 更新最大宽度
for _ in range(size):
cur=q.pop(0)# 弹出当前节点
if cur.left:# 如果有左子节点,将左子节点加入队列
q.append(cur.left)
else:# 如果没有左子节点,创建一个值为0的左子节点,并加入队列
new=TreeNode(0)
cur.left=new
q.append(cur.left)
if cur.right:# 如果有右子节点,将右子节点加入队列
q.append(cur.right)
else:# 如果没有右子节点,创建一个值为0的右子节点,并加入队列
new=TreeNode(0)
cur.right=new
q.append(cur.right)
return m# 返回最大宽度
- 超出时间限制
- 存在问题:对于示例3会给第二层都加上值为0的节点,和最后返回的结果不一样
正解:优化
- 上文新创节点实在不明智,这里直接用节点的位置索引,每一层的结束索引-开始索引+1则为该层的宽度,更新最大宽度,返回即可。
from collections import deque
class Solution:
def widthOfBinaryTree(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
q = deque([(root, 0)]) # 使用双端队列存储节点及其对应的位置索引
max_width = 0
while q:
level_size = len(q) # 当前层的节点数量
_, start = q[0] # 等于start = q[0][1]当前层最左侧的节点的位置索引,不需要节点本身,用_占位,q为元组
_, end = q[-1] # end = q[-1][1]当前层最右侧的节点的位置索引
max_width = max(max_width, end - start + 1) # 更新最大宽度
for _ in range(level_size):
node, index = q.popleft() # 从左侧弹出节点及其位置索引
# 处理左子节点
if node.left:
q.append((node.left, 2 * index)) # 左子节点的位置索引为当前节点的位置索引乘以2
# 处理右子节点
if node.right:
q.append((node.right, 2 * index + 1)) # 右子节点的位置索引为当前节点的位置索引乘以2加1
return max_width # 返回最大宽度
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人