一、求每层最多的节点
思路:层序遍历,记录每层个数。
/**
* 二叉树求宽度(求每层最多多少个节点的情况)
*/
public static int widthOfBinaryTree(TreeNode root) {
if (root == null) {
return 0;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int curCountInQueue = 1;//二叉树当前层已经存在队列中的个数
int maxwidth = 0;//节点数最大的层的节点数
while (!queue.isEmpty()) {
curCountInQueue--;
if (curCountInQueue == 0) {
maxwidth = Math.max(maxwidth, queue.size());
curCountInQueue = queue.size();
}
TreeNode temp = queue.poll();
if (temp.left != null) {
queue.add(temp.left);
}
if (temp.right != null) {
queue.add(temp.right);
}
}
return maxwidth;
}
二、二叉树最大宽度(leetcode662)
这种情况和上边有所区别,因为空节点也算在内。
思路:给二叉树按层进行编号,记录每层最左边节点编号和最右边节点编号即可算出本层宽度。(编号方法是头节点为1,编号为i的节点的左子节点编号为2*i,右子节点编号为2*i+1)可以dfs将二叉树编号
/**
* 二叉树求宽度(求每层左右两个节点相差最大是多少时,空节点也算)leetcode662
*/
public static int widthOfBinaryTree2(TreeNode root) {
//两个map分别存了当前层数最左边节点编号和最右边节点编号,key是层数,value是编号
Map<Integer, Integer> rightMap = new TreeMap<>();// key 层数 value 编号
Map<Integer, Integer> leftMap = new TreeMap<>();
dfs(root, 1, 1, leftMap, rightMap);
int max = 0;
for (int key : rightMap.keySet()) {
max = Math.max(max, rightMap.get(key) - leftMap.get(key)+ 1) ;
}
return max;
}
/**
* @param num 编号
* @param cengshu 层数
*/
public static void dfs(TreeNode root, int num, int cengshu, Map<Integer, Integer> leftMap, Map<Integer, Integer> rightMap) {
if (root == null) {
return;
}
if (!leftMap.containsKey(cengshu)) {//因为每层首先到达的是本层最左边节点,所以只需要判断最左边节点第一次到达就几率编号即可
leftMap.put(cengshu, num);
}
if (!rightMap.containsKey(cengshu) || rightMap.get(cengshu) < num) {
rightMap.put(cengshu, num);
}
dfs(root.left, 2 * num, cengshu + 1, leftMap, rightMap);
dfs(root.right, 2 * num + 1, cengshu + 1, leftMap, rightMap);
}