leetcode 662. Maximum Width of Binary Tree(二叉树的最大宽度)

在这里插入图片描述

计算二叉树的最大宽度,宽度是指每层的最右边到最左边节点的距离。
从最左边的非null节点到最右边的非null节点(包含它们中间的null节点)。

思路:

1.BFS

与以往不同的是,这里不仅仅是统计一层的节点个数,还要算上节点中间的null(左右边界外的null不算)。
把null节点也转入queue会浪费空间,还要和边界外的null区分,比较麻烦,
因为是二叉树,所以给每个节点一个id, 左节点的id = root id * 2, 右节点id = root id * 2+ 1.
id可以就这么顺序排下去,如果担心id过大会溢出,
可以让每一层的id都从0开始(cur_id = id-left)。

    public int widthOfBinaryTree(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<>();
        int maxWidth = 0;

        //用node.val保存id,这会修改掉节点值,题里不影响,实际情况要斟酌
        root.val = 0;
        queue.add(root);
        while(!queue.isEmpty()) {
            int size = queue.size();
            int left = queue.peek().val; //最左边节点的id
            int right = left;
            for(int i = 0; i < size; i++) {
                TreeNode cur = queue.poll();
                if(cur.left != null) {
                    //担心id过大,让每一层id都从0开始,其实不减left也可以,并不会超过int最大值
                    cur.left.val = (cur.val-left) * 2;
                    queue.add(cur.left);
                }
                if(cur.right != null) {
                    //担心id过大,让每一层id都从0开始,其实不减left也可以,并不会超过int最大值
                    cur.right.val = (cur.val-left) * 2 + 1;
                    queue.add(cur.right);
                }

                if(i == size - 1) right = cur.val;
            }
            maxWidth = Math.max(maxWidth, right-left+1);
        }
        return maxWidth;
    }

2.DFS

用DFS递归求每个节点的左右子树最大宽度,最大宽度是在 当前层的当前node到最左边node的距离,左子树的最大宽度,右子树的最大宽度,三者中取最大。
其中左子树宽度,右子树宽度也是递归,在 当前层的当前node到最左边node的距离,左子树的最大宽度,右子树的最大宽度,三者中取最大。
直到到达null节点,宽度返回0。

至于如何计算距离,可给每个node一个id,左子树的id就是root id✖️2,右子树id是root id✖️2+1,距离就是当前id减最左边id再加1
而如何判断最左边的id,可用一个list保存每层最左边的id。每层的第一个节点,也就是层数==list的size时加入节点id

    public int widthOfBinaryTree(TreeNode root) {
        List<Integer> ids = new ArrayList<>();
        return dfs(root, ids, 0, 0);
    }
    
    int dfs(TreeNode root, List<Integer> ids, int depth, int id) {
        if(root == null) return 0;
        if(depth == ids.size()) ids.add(id);
        
        return Math.max(id - ids.get(depth) + 1,  //当前层width
           Math.max(dfs(root.left, ids, depth+1, (id-ids.get(depth))*2), //左子树width
                       dfs(root.right, ids, depth+1, (id-ids.get(depth))*2+1)));
    }

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值