Given a binary tree, write a function to get the maximum width of the given tree. The width of a tree is the maximum width among all levels. The binary tree has the same structure as a full binary tree, but some nodes are null.

The width of one level is defined as the length between the end-nodes (the leftmost and right most non-null nodes in the level, where the null nodes between the end-nodes are also counted into the length calculation.

Example 1:

Input: 

           1
/ \
3 2
/ \ \
5 3 9 Output: 4
Explanation: The maximum width existing in the third level with the length 4 (5,3,null,9).

Example 2:

Input: 

          1
/
3
/ \
5 3 Output: 2
Explanation: The maximum width existing in the third level with the length 2 (5,3).

Example 3:

Input: 

          1
/ \
3 2
/
5 Output: 2
Explanation: The maximum width existing in the second level with the length 2 (3,2).

Example 4:

Input: 

          1
/ \
3 2
/ \
5 9
/ \
6 7
Output: 8
Explanation:The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7).

Note: Answer will in the range of 32-bit signed integer.

这道题让我们求二叉树的最大宽度,根据题目中的描述可知,这里的最大宽度不是满树的时候的最大宽度,如果是那样的话,肯定是最后一层的结点数最多。这里的最大宽度应该是两个存在的结点中间可容纳的总的结点个数,中间的结点可以为空。那么其实只要我们知道了每一层中最左边和最右边的结点的位置,我们就可以算出这一层的宽度了。所以这道题的关键就是要记录每一层中最左边结点的位置,我们知道对于一棵完美二叉树,如果根结点是深度1,那么每一层的结点数就是 2*n-1,那么每个结点的位置就是 [1, 2*n-1] 中的一个,假设某个结点的位置是i,那么其左右子结点的位置可以直接算出来,为 2*i 和 2*i+1,可以自行带例子检验。由于之前说过,我们需要保存每一层的最左结点的位置,那么我们使用一个数组 start,由于数组是从0开始的,我们就姑且认定根结点的深度为0,不影响结果。我们从根结点进入,深度为0,位置为1,进入递归函数。首先判断,如果当前结点为空,那么直接返回,然后判断如果当前深度大于 start 数组的长度,说明当前到了新的一层的最左结点,我们将当前位置存入 start 数组中。然后我们用 idx - start[h] + 1 来更新结果 res。这里 idx 是当前结点的位置,start[h] 是当前层最左结点的位置。然后对左右子结点分别调用递归函数,注意左右子结点的位置可以直接计算出来,代码参见评论区二楼。我们也可以让递归函数直接返回最大宽度了,但是解题思路没有啥区别,代码参见评论区三楼。这两种方法之前都能通过 OJ,直到后来加了一个很极端的 test case,使得二者都整型溢出了 Signed Integer Overflow,原因是这里每层都只有1个结点,而我们代码中坐标每次都要乘以2的,所以到32层以后就直接溢出了。为了避免溢出的问题,需要做些优化,就是要统计每层的结点数,若该层只有一个结点,那么该层结点的坐标值重置为1,这样就可以避免溢出了。所以 DFS 的解法就不能用了,只能用层序遍历,迭代的方法来写,这里使用了队列 queue 来辅助运算,queue 里存的是一个 pair,结点和其当前位置,在进入新一层的循环时,首先要判断该层是否只有1个结点,是的话重置结点坐标位置,再将首结点的位置保存出来当作最左位置,然后对于遍历到的结点,都更新右结点的位置,遍历一层的结点后来计算宽度更新结果 res,参见代码如下:

class Solution {
public:
int widthOfBinaryTree(TreeNode* root) {
if (!root) return ;
int res = ;
queue<pair<TreeNode*,int>> q;
q.push({root, });
while (!q.empty()) {
if (q.size() == ) q.front().second = ;
int left = q.front().second, right = left, n = q.size();
for (int i = ; i < n; ++i) {
auto t = q.front().first;
right = q.front().second; q.pop();
if (t->left) q.push({t->left, right * });
if (t->right) q.push({t->right, right * + });
}
res = max(res, right - left + );
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/662

参考资料:

https://leetcode.com/problems/maximum-width-of-binary-tree/

https://leetcode.com/problems/maximum-width-of-binary-tree/discuss/327721/cpp-bfs-solution

https://leetcode.com/problems/maximum-width-of-binary-tree/discuss/106654/javac-very-simple-dfs-solution

https://leetcode.com/problems/maximum-width-of-binary-tree/discuss/106645/cjava-bfsdfs3liner-clean-code-with-explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Maximum Width of Binary Tree 二叉树的最大宽度的更多相关文章

  1. [LeetCode] 662. Maximum Width of Binary Tree 二叉树的最大宽度

    Given a binary tree, write a function to get the maximum width of the given tree. The width of a tre ...

  2. 662. Maximum Width of Binary Tree二叉树的最大宽度

    [抄题]: Given a binary tree, write a function to get the maximum width of the given tree. The width of ...

  3. [LeetCode] Maximum Depth of Binary Tree 二叉树的最大深度

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  4. [Leetcode] Maximum depth of binary tree二叉树的最大深度

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  5. [LeetCode]662. Maximum Width of Binary Tree判断树的宽度

    public int widthOfBinaryTree(TreeNode root) { /* 层序遍历+记录完全二叉树的坐标,左孩子2*i,右孩子2*i+1 而且要有两个变量,一个记录本层节点数, ...

  6. 【LeetCode】662. Maximum Width of Binary Tree 解题报告(Python)

    [LeetCode]662. Maximum Width of Binary Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.co ...

  7. [LeetCode] 543. Diameter of Binary Tree 二叉树的直径

    Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a b ...

  8. LeetCode——Maximum Depth of Binary Tree

    LeetCode--Maximum Depth of Binary Tree Question Given a binary tree, find its maximum depth. The max ...

  9. LC 662. Maximum Width of Binary Tree

    Given a binary tree, write a function to get the maximum width of the given tree. The width of a tre ...

随机推荐

  1. USACO Humble Numbers

    USACO  Humble Numbers 这题主要是两种做法,第一种是比较常(jian)规(dan)的-------------用pq(priority_queue)维护,每次取堆中最小值(小根堆) ...

  2. 从源码来看ReentrantLock和ReentrantReadWriteLock

    上一篇花了点时间将同步器看了一下,心中对锁的概念更加明确了一点,知道我们所使用到的锁是怎么样获取同步状态的,我们也写了一个自定义同步组件Mutex,讲到了它其实就是一个简版的ReentrantLock ...

  3. 线程池与Python中的GIL

    线程池是一个操作系统的概念,它是对多线程的一种优化. 多线程的时候,创建和销毁线程伴随着操作系统的开销,如果频繁创建/销毁线程,则会使效率大大降低. 而线程池,是先创建出一批线程放入池子里,需要创建线 ...

  4. 从Firefox升级说学习方法

    今天早上,打开PortableAPPs时,它提示我升级FireFox,跟往常一样我没考虑就升级了. 打开Firefox 57神速,很是惊喜,打开后发现悲剧了,自己(通过下载插件)定制的功能都不能使用了 ...

  5. alpha-咸鱼冲刺day7(后续一波)-紫仪

    总汇链接 一,合照 emmmmm.自然还是没有的. 二,项目燃尽图 三,项目进展 正在写登陆+注册ing 注册搞出来了!!!!!!!!QAQ(喜极而泣!!!!.jpg) 四,问题困难 数据流程大概是搞 ...

  6. Tornado 网站demo 二

    连接数据库 methods 中建立一个文件 db.py 分别建立起连接对象和游标对象 #!/usr/bin/env Python # coding=utf-8 import pymysql conn ...

  7. scrapy 模拟登陆

    import scrapy import urllib.request from scrapy.http import Request,FormRequest class LoginspdSpider ...

  8. Flask 测试

    测试是每个应用系统发布前必须经历的步骤,自动化测试对测试效率的提高也是毋庸置疑的.对于Flask应用来说,当然可以使用Web自动化测试工具,比如Selenium等来测.Flask官方推荐的自动化测试方 ...

  9. python 操作Memcached

    启动Memcached memcached -d -m 10 -u root -l 10.211.55.4 -p 12000 -c 256 -P /tmp/memcached.pid 参数说明: -d ...

  10. vue 内联样式style中的background

    在我们使用vue开发的时候   有很多时候我们需要用到背景图 这个时候会直接使用 内联样式 直接把你拿到的数据拼接上去 注意  在vue中直接使用style时 花括号一定别忘记 还有就是你的url一定 ...