题目描述
最大宽度就是求出每层的节点数,找出最多的那一个,返回节点数值.这和leetcode中右一题返回最大宽度是不同的,leetcode是根据占据的宽度来计算的,null 也会算上,我们这题只计算实际有的节点值,leetcode 上的那个计算最大宽度,有空会出个答案的.
第一种解题方式
第一种: 我们通过按层遍历的方式,去遍历这个树,遍历的过程中 我们用一个hashmap表记录每个节点所在的层数.根据所在的层数,我们就可以统计出每层的节点数.返回最大值就可以了.
先定义一个二叉树
public class Node{
int val;
Node left;
Node right;
public Node(int val) {
this.val = val;
}
}
解题代码:
public static int getMaxWidth(Node head){
if (head == null){
return 0;
}
Queue<Node> queue = new LinkedList<>();
queue.add(head);
//记录当前节点和其所在层数
HashMap<Node, Integer> map = new HashMap<>();
map.put(head,1);
//当前层的节点数
int curLeverNodes = 0;
//当前层数
int curLevel = 1;
int max = 0;
while (!queue.isEmpty()){
Node node = queue.poll();
Integer level = map.get(node);
if (node.left != null){
queue.add(node.left);
map.put(node.left,level +1);
}
if (node.right != null){
queue.add(node.right);
map.put(node.right,level + 1);
}
//如果在同一层 ,节点数 直接增加
if (level == curLevel){
curLeverNodes++;
}else{
//如果来到下一层先保存住最大宽度
max = Math.max(max,curLeverNodes);
//第一次来到下一层 ,后面会继续跑进if的逻辑里
curLevel++;
//节点数量第一次 初始化为1
curLeverNodes = 1;
}
}
return Math.max(curLeverNodes,max);
}
第二种解题方式
我们可以不用map集合去记录每个节点所在的层,我们用几个有限的变量也可以实现计算每层的宽度.当然还是用按层遍历的方式去遍历二叉树.遍历的过程中,我们记录住当前层的最右节点和下一层的最右节点,根据什么时候跑到最右节点就可以计算出当前层的宽度
/**
* 进阶的方法 不用map 集合
* 还是按层遍历的方式去遍历这个二叉树,在遍历的过程中记录住,
* 当前层的最右节点和下一层的最右节点,
* @param head
* @return
*/
public static int maxWidth(Node head){
if (head == null){
return 0;
}
Queue<Node> queue = new LinkedList<>();
queue.add(head);
//当前层的最右节点
Node curEnd = head;
//下一层的最右节点
Node nextEnd = null;
//最大节点数
int max = 0;
//当前层的节点数
int curLevelNodes = 0;
while (!queue.isEmpty()){
Node node = queue.poll();
if (node.left != null){
queue.add(node.left);
nextEnd = node.left;
}
if (node.right != null){
queue.add(node.right);
nextEnd = node.right;
}
curLevelNodes++;
//当前节点是否是最右节点,不是就继续跑,宽度自增 是最右节点的话,
if (node == curEnd){
//先比较下最大宽度,
max = Math.max(max,curLevelNodes);
当前最右节点换成下一层的最右节点,开启下一层的遍历
curEnd = nextEnd;
//宽度置为0
curLevelNodes = 0;
}
}
return max;
}