题目地址:
https://www.lintcode.com/problem/maximum-width-of-binary-tree/description
给定一棵二叉树,求其每一层宽度的最大者。对于一棵二叉树而言,其某一层的宽度是指,想象从树根到这一层撑出一棵Full Binary Tree,这一层的最左边和最右边的非null节点及其中间所有null节点组成的list的size即为这一层的宽度。
要知道某一层的宽度,必须知道这一层的最左边的非null节点和最右边的非null节点在Full Binray Tree里的编号。至于宽度,只需要将两个编号相减再加一就得到了。所有我们想到在BFS的同时维护一个双端队列,专门offer节点编号进去。而已知树根的编号的情况下,其左右孩子的编号是很好确定的(设树根的编号为 0 0 0,那么如果某个节点编号是 n n n,其左孩子的编号就是 2 n + 1 2n+1 2n+1,其右孩子的编号就是 2 n + 2 2n+2 2n+2)。然后每一层遍历完后就把双端队列两个端点取出来做差再加一就得到了这一层的宽度。代码如下:
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
/**
* @param root: the root
* @return: the maximum width of the given tree
*/
public int widthOfBinaryTree(TreeNode root) {
// Write your code here
if (root == null) {
return 0;
}
// 同时维护两个队列,两个队列同时offer,同时poll
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
Deque<Integer> deque = new ArrayDeque<>();
deque.offer(0);
int res = 0;
while (!queue.isEmpty()) {
// 算一下当前要遍历的层的宽度
res = Math.max(res, deque.peekLast() - deque.peekFirst() + 1);
// 分层遍历要记录队列的size
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode x = queue.poll();
int num = deque.poll();
if (x.left != null) {
queue.offer(x.left);
deque.offer(2 * num + 1);
}
if (x.right != null) {
queue.offer(x.right);
deque.offer(2 * num + 2);
}
}
}
return res;
}
}
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int x) {
val = x;
}
}
时空复杂度 O ( n ) O(n) O(n)。