思路分析:
-
* 假设满二叉树表示成数组序列, 根节点所在的位置为1,
-
* 则任意位于i节点的左右子节点的pos为2*i, 2*i+1。
-
* 用一个List保存每层的左端点,易知二叉树有多少层List的元素就有多少个。
-
* 那么可以在dfs的过程中记录每个节点的pos及其所在的层level,
-
* 如果level>List.size()说明当前节点就是新的一层的最左节点, 将其 加入List中,
-
* 否则判断当前节点的index减去List中对应层的最左节点的pos的宽度是否大于最大宽度并更新
代码实现
class Width {
private int maxWidth = 0;
public int widthOfBinaryTree(TreeNode root){
List<Integer> list = new ArrayList<>();//记录每层最左节点
dfs(root, 1, 1, list);
}
public void dfs(TreeNode root, int level, int pos, List<Integer> list){
if(root == null)
return;
if(level > list.size()){
list.add(pos);
}
//list.get(level-1)减1是因为根节点第一层的位置从索引0得位置存入,第二层最左端的从索引1
//存入,则第 n 层,最左端节点的位置 pos 是 list.get(level)
maxWidth = Math.max(maxWidth, pos - list.get(level - 1) + 1);
//遍历左子树
dfs(root, level + 1, pos*2, list);
//遍历右子树
dfs(root, level + 1, pos*2+1, list);
}
}
方法二:
队列+层序遍历
实现代码:
public int widthOfBinaryTree(TreeNode root) {
// edge cases
if(root == null) {
return 0;
}
// BFS
int maxWidth = 0;
Queue<TreeNode> queue = new LinkedList<>();
// Queue<Integer> locQueue = new LinkedList<>();
root.val = 1;
queue.offer(root);
while(!queue.isEmpty()) {
int size = queue.size();
// 记录该行第一/最后一个node的位置信息,在i = 0 和 i = size - 1时更新
int first = 0;
int last = 0;
for(int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if(i == 0) first = node.val;
if(i == size - 1) last = node.val;
if(node.left != null) {
node.left.val = node.val * 2;
queue.offer(node.left);
}
if(node.right != null) {
node.right.val = node.val * 2 + 1;
queue.offer(node.right);
}
}
maxWidth = Math.max(maxWidth, last - first + 1);
}
return maxWidth;
}