题目描述(难度中等)
给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(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)。
注意: 答案在32位有符号整数的表示范围内。
解题思路[1]
将二叉树的下标存储到数组中:
根节点下标为 1,左子树结点为 2 * i,右子树下标为 2 * i+1;然后我们层次遍历,每次比较最大宽度值。
但是这个题目有个恶心的例子,全部节点都只有右子树。按照上面的编码,后面的编号就要爆炸。所以做一个优化就是每当对下一层的节点进行编号的时候,减去上一层最左边的编号,这样就可以保证编号不会超出题目要求的int的范围。[2]
代码如下
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int widthOfBinaryTree(TreeNode* root) {
int width=0;
if(root==NULL)//边界情况
return width;
queue<pair<TreeNode*,int>> q;
q.push(make_pair(root,1));
while(!q.empty())
{
int size=q.size();//当前层非空节点数
int pos=q.front().second;//当前层第一个节点的编号
for(int i=0;i<size;i++)
{
pair<TreeNode*,int> p=q.front();
q.pop();
if(p.first->left)
//减去pos是为了防止越界,这样每层的编号都是从1开始
q.push(make_pair(p.first->left,p.second*2-pos));
if(p.first->right)
q.push(make_pair(p.first->right,p.second*2+1-pos));
if(width<p.second-pos+1)
width=p.second-pos+1;
}
}
return width;
}
};
提交结果:
参考
- ^https://leetcode-cn.com/problems/maximum-width-of-binary-tree/solution/ceng-ci-bian-li-shi-xian-by-aaron_yu/
- ^https://leetcode-cn.com/problems/maximum-width-of-binary-tree/solution/yi-ceng-ceng-bian-ma-hou-bian-li-zhu-yi-bian-hao-y/