LeetCode 662.二叉树最大宽度

本文介绍了如何使用宽度优先遍历来求解二叉树的最大宽度。通过定义一个辅助节点类型helpNode,包含节点、所在层数和位置索引,利用队列进行BFS遍历,动态更新当前层最左边节点的位置,并计算最大宽度。代码配合详细注释帮助理解算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空
定义宽度为:每一层最左边非空节点和最右边非空节点之间的距离

思路

最容易想到的就是宽度优先遍历(BFS) 或者 深度优先遍历(DFS)
本文以宽度优先遍历进行阐述。

  1. 我们知道二叉树的根节点和孩子节点索引的关系为:假设根节点索引为index,那么该节点左孩子的索引就为2*index + 1,右孩子就为2*index + 2
  2. 所以,每一层中的宽度都可以通过不断遍历当前层的节点位置索引–当前层最左边的非空节点位置索引+1,然后取最大值来确定每一层的最大宽度,这样就能找到整个树的最大宽度
  3. 我们可以定义一个辅助节点类型helpNode,包含三个属性:每个节点本身TreeNode以及当前节点所在的层数depth当前节点的位置索引pos
  4. helpNode用一个队列queue来保存,这样通过遍历二叉树中的每一个非空节点,遍历完成,最大宽度也就找到了

以下为代码+注释,看代码配合注释应该好理解一点:


// 定义TreeNode树节点
	class TreeNode{
		int val;
		TreeNode left;
		TreeNode right;
		TreeNode(int val){
			this.val = val;
		}
	}
// 额外定义一个辅助节点,存放当前节点以及节点所在层和位置
    class helpNode{
        TreeNode node;
        int depth;
        int pos;
        helpNode(TreeNode node, int depth, int pos){
            this.node = node;
            this.depth = depth;
            this.pos = pos;
        }
    }
    //主方法
    public int widthOfBinaryTree(TreeNode root) {
        if(root == null)
            return 0;
        // 定义一个变量表示当前所在层数
        int curLevel = 1;
        // 定义每一层最左边的那个节点的位置索引,初始化为1
        int leftOne = 1;
        // 定义一个队列存放helpNode类型的节点
        Queue<helpNode> queue = new LinkedList<>();
        // 初始化先将根节点加入队列
        queue.offer(new helpNode(root, 1, 1));
        // 设置一个变量存储当前情况的最大宽度
        int res = Integer.MIN_VALUE;
        // 宽度优先遍历,将二叉树中的节点全部遍历一遍
        while(!queue.isEmpty()){
            helpNode cur = queue.poll();
            // 取出当前节点所在层
            int curNodeLevel = cur.depth;
            // 如果当前节点所在的层数和当前正在遍历的层数不相等
            // 说明已经走到下一层了,更新leftOne和curLevel
            if(curNodeLevel != curLevel){
                curLevel = curNodeLevel;
                //因为当前现在是第一个不在遍历层的节点,它属于下一层
                //并且节点是从左到右加入队列的,而且队列是先进先出
                //所以我一定是下一层的第一个非空节点!
                leftOne = cur.pos;
            }
            // 如果当前节点有左孩子或右孩子,就将其加入队列
            if(cur.node.left != null)
                queue.offer(new helpNode(cur.node.left, curNodeLevel + 1, 2 * cur.pos + 1));
            if(cur.node.right != null)
                queue.offer(new helpNode(cur.node.right, curNodeLevel + 1, 2 * cur.pos + 2));
            // 将当前节点和当前层最左边的节点的距离每次都和最大值作比较进行更新
            res = Math.max(res, cur.pos - leftOne + 1);
        }
        // 最后返回最终结果,一定是最大宽度
        return res;
    }

笔者也在不断学习中,如有错误,欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值