如何求一个二叉树的最大宽度
可以借助容器,也可以使用标记
一、使用容器
思路:
使用HashMap,键为结点对象,值为层级
层序遍历二叉树,取出当前结点的层级,和当前遍历的层级对比,如果相等,则本层节点数++,如果不等,则说明进入了下一层,本层节点数和最大宽度对比,然后重置本层结点数。
public static int maxWidthUseMap(Node head) {
if (head == null) {
return 0;
}
Queue<Node> queue = new LinkedList<>();
queue.add(head);
// key 在 哪一层,value
HashMap<Node, Integer> levelMap = new HashMap<>();
levelMap.put(head, 1);
int curLevel = 1; // 当前你正在统计哪一层的宽度
int curLevelNodes = 0; // 当前层curLevel层,宽度目前是多少
int max = 0;
while (!queue.isEmpty()) {
Node cur = queue.poll();
int curNodeLevel = levelMap.get(cur);
if (cur.left != null) {
levelMap.put(cur.left, curNodeLevel + 1);
queue.add(cur.left);
}
if (cur.right != null) {
levelMap.put(cur.right, curNodeLevel + 1);
queue.add(cur.right);
}
if (curNodeLevel == curLevel) {
curLevelNodes++;
} else {
max = Math.max(max, curLevelNodes);
curLevel++;
curLevelNodes = 1;
}
}
max = Math.max(max, curLevelNodes);
return max;
}
二、标记末尾结点
思路:
准备一个当前层的尾结点curEnd和一个下一层的尾结点nextEnd
层序遍历树,如果有左子或右子,nextEnd=左子或右子,最后nextEnd即为下一层的尾结点。
如果当前弹出的结点不为 curEnd,则当前层节点数++,如果当前弹出的结点为curEnd,说明该进入下一层了。
当前层节点数和最大层节点数对比,然后当前层结点数清零,curEnd=nextEnd。
public static int maxWidthNoMap(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 curWidth = 0;
while (!queue.isEmpty()) {
Node cur = queue.poll();
curWidth++;
if (cur.left != null) {
queue.add(cur.left);
nextEnd = cur.left;
}
if (cur.right != null) {
queue.add(cur.right);
nextEnd = cur.right;
}
if (cur == curEnd) {
max = Math.max(max, curWidth);
curWidth = 0;
curEnd = nextEnd;
}
}
return max;
}