1.题目


2.思路
q:存真实的树节点
list:存与 q 中节点一一对应的"位置编号 index"
(1)用 BFS 按层遍历二叉树。同时维护两份同步结构:
q 存当前层的真实节点;
list 存这些节点在完全二叉树中的位置编号 index。
(2)编号规则:
根节点 index = 1
左孩子 = 2 * index
右孩子 = 2 * index + 1
(3)每处理完一层:
q 和 list 中剩下的就是下一层的节点及其编号。
下一层宽度 = list.getLast() - list.getFirst() + 1
(4)res 记录所有层中最大的宽度。
例子1:
java
1
/ \
3 2
/ \ \
5 3 9


补充:
list 这个链表的头部取出并删除第一个元素

3.代码实现
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int widthOfBinaryTree(TreeNode root) {
if(root==null)
{
return 0;
}
//记录当前节点
Queue<TreeNode> q=new LinkedList<>();
//记录当前节点的索引
LinkedList<Integer> list=new LinkedList<>();
q.offer(root);
list.add(1);
int res=1;
while(!q.isEmpty())
{ //记录当前层的元素个数
int cnt=q.size();
//q.poll() 取出来的都是从左到右的层序顺序。
for(int i=0;i<cnt;i++)
{
//队列弹出第一个元素
TreeNode cur=q.poll();
//列表删除第一个元素并且赋值给curIndex
Integer curIndex=list.removeFirst();
//当前元素的左孩子不为空
if(cur.left!=null)
{//左孩子入队
q.offer(cur.left);
//记录左孩子的索引
list.add(curIndex*2);
}
if(cur.right!=null)
{ //右孩子入队
q.offer(cur.right);
//记录右孩子索引
list.add(curIndex*2+1);
}
}
if(list.size()>0)
{
res=Math.max(res,list.getLast()-list.getFirst()+1);
}
}
return res;
}
}