题目
leetcode 原题出处:662. 二叉树最大宽度 - 力扣(LeetCode)
- 给你一棵二叉树的根节点 root ,返回树的最大宽度 。
- 树的最大宽度是所有层中最大的 宽度 。
- 每一层的宽度被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度。
思路
-
BFS+编号(满二叉树性质)
- 根据层序遍历的逻辑在添加一个队列用于记录当前这一层所有结点的编号,记录编号的公式是根据满二叉树性质得出的(自己推也行)
- 每一次迭代结束后(也就是当前层的所有结点都已被遍历完成),这个时候就要比较最大宽度了,这里我们假设在初始化时设置了一个变量用来记录最大宽度
maxWidth
,那么在每一次遍历结束就需要进行比较&&更新操作:maxWidth=Math.max(maxWidth,indexQueue.peeklast-indexQueue.peek+1);
- 最后将
maxWidth
返回即可。
这里是视频讲解:Leetcode力扣662 手画图解版|二叉树最大宽度 Maximum Width of Binary Tree_哔哩哔哩_bilibili
代码实现
/**
* 计算二叉树的最大宽度
*
* @param root 二叉树根节点
* @return 最大宽度数
*/
public int widthOfBinaryTree(TreeNode root) {
Deque<TreeNode> treeNodeQueue = new ArrayDeque<>();
Deque<Integer> integerQueue = new ArrayDeque<>();
int maxWidth = 0;
// int curLevel = 1;
treeNodeQueue.offer(root);
integerQueue.offer(1);
while (!treeNodeQueue.isEmpty() && !integerQueue.isEmpty()) {
int size = treeNodeQueue.size();
// curLevel++;
while (size-- > 0) {
TreeNode poll = treeNodeQueue.poll();
Integer preIndex = integerQueue.poll();
assert poll != null;
assert preIndex != null;
if (poll.left != null) {
treeNodeQueue.offer(poll.left);
integerQueue.offer(preIndex * 2);
}
if (poll.right != null) {
treeNodeQueue.offer(poll.right);
integerQueue.offer(preIndex * 2 + 1);
}
}
if (!integerQueue.isEmpty()) {
maxWidth = Math.max(maxWidth, integerQueue.peekLast() - integerQueue.peek() + 1);
}
//清空记录下标的队列
// integerQueue.clear();
}
return maxWidth;
}