在力扣上也有一道是求二叉树最大宽度的题,但是那里面要求空节点也要算上,这里面的是不包含空节点的。力扣上面实现方法和本文的第二种方法(不用hash)类似。题目链接,本人实现的题解。
在求二叉树最大宽度上面使用了两种实现方法,第一种是使用了hash法,第二种未使用。代码如下。
哈希法:
//求二叉树的宽度 不包括空节点
//哈希法
public int hashWidthOfBinaryTreeNoNullNode(TreeNode root) {
if(root == null){
return 0;
}
//最大宽度
int max = 0;
//使用一个队列来临时存储结点值
Queue<TreeNode> queue = new LinkedList<>();
//使用一个Map集合来存储对应层级的信息
// key -- 当前结点 value -- 当前结点所在层级
Map<TreeNode, Integer> map = new HashMap<>();
//map中先存储进根结点 key--root value--第一层
map.put(root, 1);
queue.offer(root);
//当前结点所在层级
int curNodeLevel = 0;
//当前正在统计的层级
int curCountLevel = 1;
//当前层级的结点数
int curNodeCount = 0;
while (!queue.isEmpty()) {
//取出队头元素
root = queue.poll();
//获取当前结点所在的层级
curNodeLevel = map.get(root);
//判断他是否有左孩子 如果有,连同左孩子和当前孩子所在层级(队头结点的层级 + 1)存入到map中
if (root.left != null) {
map.put(root.left, curNodeLevel + 1);
//队列中也存储左孩子结点
queue.offer(root.left);
}
//判断是否有右孩子 如果有 连同右孩子和所在层级存入到map
if (root.right != null) {
map.put(root.right, curNodeLevel + 1);
queue.offer(root.right);
}
//处理当前队头结点
//如果当前队头结点的所在层级 和我正在统计的层级一致 那么我要将当前层级的结点数加一
if (curNodeLevel == curCountLevel) {
curNodeCount++;
} else {
//如果不一致,证明我当前正在统计的层级已经没有新结点了,可以结算了
//获取上一层和当前层结点数的最大值
max = Math.max(max, curNodeCount);
//我正在统计的层级也要加一
curCountLevel ++;
//当前层级的结点数变成0 但是由于当前结点已经是下一层的了 所以变成1
curNodeCount = 1;
}
}
//循环结束后,还有一个层级未统计
max = Math.max(max,curNodeCount);
return max;
}
非哈希法:
//求二叉树的宽度 不包括空节点
//使用两个索引记录左右两边的位置
//非哈希法
public int noHashWidthOfBinaryTreeNoNullNode(TreeNode root){
if(root == null){
return 0;
}
int width = 0;
Queue<TreeNode> nodes = new LinkedList<>();
nodes.offer(root);
//记录当前层的最后一个结点
//首先是根结点 默认在root上 后面的所有层都需要进行移动
TreeNode curEnd = root;
//记录下一层的最后一个结点(从第一个结点开始往后移动,一直移动到下一层的最后一个右结点)
TreeNode nextLevelEnd = null;
//记录结点数
int nodesCount = 0;
while(!nodes.isEmpty()){
TreeNode cur = nodes.poll();
//判断是否有左右孩子 如果有 设置nextLevelEnd的指向
if(cur.left != null){
nodes.offer(cur.left);
nextLevelEnd = cur.left;
}
if(cur.right != null){
nodes.offer(cur.right);
nextLevelEnd = cur.right;
}
//结点数加加
nodesCount ++;
//如果当前的结点来到了这一层的最后一个结点位置 代表这一层要结束了,结算
//进行结算
if(curEnd == cur){
width = Math.max(width,nodesCount);
//节点数归0
nodesCount = 0;
//走到这代表上一层已经结束了,让当前层最后一个结点指针curEnd指向下一层的结点指针
curEnd = nextLevelEnd;
}
}
return width;
}