给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空。
每一层的宽度被定义为两个端点(该层最左和最右的非空节点,两端点间的null节点也计入长度)之间的长度。
示例 1:
输入:
1
/ \
3 2
/ \ \
5 3 9
输出: 4
解释: 最大值出现在树的第 3 层,宽度为 4 (5,3,null,9)。
示例 2:
输入:
1
/
3
/ \
5 3
输出: 2
解释: 最大值出现在树的第 3 层,宽度为 2 (5,3)。
示例 3:
输入:
1
/ \
3 2
/
5
输出: 2
解释: 最大值出现在树的第 2 层,宽度为 2 (3,2)。
示例 4:
输入:
1
/ \
3 2
/ \
5 9
/ \
6 7
输出: 8
解释: 最大值出现在树的第 4 层,宽度为 8 (6,null,null,null,null,null,null,7)。
注意: 答案在32位有符号整数的表示范围内。
思路:先DFS遍历ROOT节点,将所有节点的下标放入MAP,方便计算宽度
public static void dfs(TreeNode root, Map<TreeNode, Integer> list, int index) { list.put(root, index); if (root.left != null) { dfs(root.left, list, 2*index); } if (root.right != null) { dfs(root.right, list,2*index + 1); } }
然后宽度遍历整颗树,map放入节点的层级。然后看下一个节点是否不是当前层级, 如果不是当前层级,就计算当前层级的宽度(用到上面的indexMap)。取每个层级宽度的做大值。 public int widthOfBinaryTree(TreeNode root) { if (root == null) { return 0; } Queue<TreeNode> queue = new ArrayDeque<>(); queue.offer(root); int curMax = 1; Map<TreeNode, Integer> map = new HashMap<>(); Map<TreeNode, Integer> indexMap = new HashMap<>(); dfs(root, indexMap, 1); map.put(root, 1); int curLev = 1; int startIndex = 1; while (!queue.isEmpty()) { //当前节点 TreeNode cur = queue.poll(); //当前节点深度还在持续 if (cur.left != null) { map.put(cur.left, curLev + 1); queue.offer(cur.left); } if (cur.right != null) { map.put(cur.right, curLev + 1); queue.offer(cur.right); } //下一个节点 TreeNode next = queue.peek(); //下一个节点的深度 int nextLev = 999999999; if (next != null) { nextLev = map.get(next); } //下一个节点的深度和当前不一致 if (nextLev != curLev && next != null) { //节点最大值 curMax = Math.max(curMax, indexMap.get(cur) - startIndex + 1); if (map.get(next) != null) { //进入下一个 startIndex = indexMap.get(next); curLev++; } } else if (next == null) {//结束了 curMax = Math.max(curMax, indexMap.get(cur) - startIndex + 1); } } return curMax; } 虽然代码内存消耗过大,但总算是找到了解决方法。