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. java高并发锁的三种实现

    提到锁大家会想到Synchronized同步关键字,使用它确实可以解决一切并发问题,但是对于体统吞吐量要求更高,在这里提供了几个小技巧.帮助大家减少锁粒度.提高系统的并发能力 一.乐观锁 试用场景:读 ...

  2. Tomcat 8启动速度慢原因1: At least one JAR was scanned for TLDs yet contained no TLDs

    最近使用tomcat8启动项目时,发现At least one JAR was scanned for TLDs yet contained no TLDs这一步加载时间非常长, 从网上收集了各种资料 ...

  3. Oracle profile 使用技巧

    给scott用户分配一个profile要求如下: 1.尝试登录的次数最多4次: 2.如果4次输入错误,则锁定该用户2天: 3.密码每隔5天修改一次,宽限期为2天: 答: SQL>conn sys ...

  4. SQL中的DML、DDL以及DCL

    DML(data manipulation language)是数据操纵语言:它们是SELECT.UPDATE.INSERT.DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的 ...

  5. 跨平台原生AR/VR应用研发引擎-NVisionXR开放内测

      NVisionXR引擎正式开放内测.现在,对原生AR/VR应用开发有兴趣的企业和开发者均可通过NVisionXR官网(www.nvisionxr.com)申请试用. NVisionXR引擎介绍视频 ...

  6. 使用.NET开发AutoCAD——C#/AutoCAD 2018/ObjectArx/二次开发入门(二)

    1.开发环境配置: (1)安装AutoCAD2018: (2)安装VS2015: (3)安装ObjectARX 2018类库: (4)安装ObjectARX 2018 .NET开发向导(ObjectA ...

  7. Linux进程间通信-消息队列(mqueue)

    前面两篇文章分解介绍了匿名管道和命名管道方式的进程间通信,本文将介绍Linux消息队列(posix)的通信机制和特点. 1.消息队列 消息队列的实现分为两种,一种为System V的消息队列,一种是P ...

  8. 个人作业Week3-案例分析

    DeadLine:2017.10.13 23:00 声明:本作业以邹欣老师博客 http://www.cnblogs.com/xinz/archive/2012/03/26/2417699.html ...

  9. 基于scrapy爬虫的天气数据采集(python)

    基于scrapy爬虫的天气数据采集(python) 一.实验介绍 1.1. 知识点 本节实验中将学习和实践以下知识点: Python基本语法 Scrapy框架 爬虫的概念 二.实验效果 三.项目实战 ...

  10. [JCIP笔记] (二)当我们谈线程安全时,我们在谈论什么

    总听组里几个大神说起线程安全问题.本来对"线程安全"这个定义拿捏得就不是很准,更令人困惑的是,大神们用这个词指代的对象不仅抽象而且千变万化.比如,我们的架构师昨天说: " ...