给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(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)。
重点两个:
1)左右节点下标的计算 2 * i 及 2* i + 1
2)如何防止极端情况整数越界。有一个用例是线性的树,所以如果每层都乘以2很快就越界了(2^32即越界)。我们采用每次进入新的一层的时候记录queue 头部的index - 1 作为delta。这样每个坐标都减去delta重新调整为从1开始,而且保持相对位置关系不变,避免了越界。这样用int类型就可以了,否则unsigned long long 都不够用,照样越界。
class Solution {
public:
int widthOfBinaryTree(TreeNode* root) {
if (!root) return 0;
int res = 1;
queue<TreeNode*> q{{root}};
list<int> idxlist = {1};
while (!q.empty()) {
int size = q.size();
int deta = idxlist.front() - 1;
for (int i=0; i<size; ++i) {
int index = idxlist.front();
idxlist.pop_front();
index -= deta;
TreeNode* tmp = q.front();
q.pop();
if (tmp->left) {
q.push(tmp->left);
idxlist.push_back(2*index);
}
if (tmp->right) {
q.push(tmp->right);
idxlist.push_back(2*index+1);
}
}
res = max(res, idxlist.back()-idxlist.front()+1);
}
return res;
}
};