二叉树最大宽度
给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(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)。
思路:
这道题具体比题目看起来要难。
我一开始以为就是层序遍历然后找到最长的那一层不就好了吗?但请注意题目中对宽度的定义:最左和最右的非空节点之间的长度。
所以这道题有两种解决方式,都是在层序遍历的基础上增加一点修改,但有些区别。
第一种方式就是我们将None值也添加进遍历结果,这样拿到每一层(包含None)的节点们后,我们处理掉左右两边的None后,就可以得到题目中定义宽度的部分。这一种方式的层序遍历以前也写过,比较简单,但后续处理掉两边的None可能有点麻烦,总体还是可行的。因为这种方法实在是没什么新意,带None的层序遍历上篇刚写过类似的,代码就先不写了。
我准备写一下第二种方法,因为第二种方法用了一个有趣的结论。
第二种方式就是我们就用最标准的层序遍历,不将None保留,但需要动用一个小结论:就是在二叉树中,假如一个节点它的位置为x,那么它的左子节点的位置就是2*x,右子节点的位置就是2*x+1。
这里说的位置就是从上到下,从左到右的标号,如下图所示:
因此我们要求二叉树的宽度时,知道某一层的左右节点之后,直接将他们的位置做差不就完了吗?如何求并记录位置也很简单,我们层序遍历时不再只添加值,而是添加元组(值,位置),让每一个节点除了值之外还绑定位置。
直接看代码吧~
代码:
class Solution(object):
def widthOfBinaryTree(self, root):
max_len=0
q=[(root,1)]#存放的时候,节点就包括两个值,根节点初始化位置为1
while(q):#标准层序遍历
rr = []
for i in range(len(q)):#只弹出那一层的元素数
a = q.pop(0)#取出来
rr.append(a)
if a[0].left:#只有又左右节点的时候才添加 不添加None
q.append((a[0].left,2*a[1]))#添加两个元素,(值,位置)
if a[0].right:#左节点的位置就是2*a[1],右节点则是2*a[1]+1
q.append((a[0].right,2*a[1]+1))
#cur_len等于这一层最后节点的位置 – 第一个节点的位置 + 1
cur_len = (rr[-1][1]-rr[0][1]+1) #拿到这一层宽度
max_len = max(max_len,cur_len)#并尝试更新
return max_len
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了