【leetcode】622 二叉树的最大宽度

题目描述

给你一棵二叉树的根节点 root ,返回树的 最大宽度 。

树的 最大宽度 是所有层中最大的 宽度 。

每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度。

题目数据保证答案将会在  32 位 带符号整数范围内。

示例 1:

输入:root = [1,3,2,5,3,null,9]
输出:4
解释:最大宽度出现在树的第 3 层,宽度为 4 (5,3,null,9) 。

示例 2:


输入:root = [1,3,2,5,null,null,9,6,null,7]
输出:7
解释:最大宽度出现在树的第 4 层,宽度为 7 (6,null,null,null,null,null,7) 。

示例 3:

输入:root = [1,3,2,5]
输出:2
解释:最大宽度出现在树的第 2 层,宽度为 2 (3,2) 。

解题思路 

        第一次看到这道题的时候,求树的最大宽度,想着直接对二叉树进行层序遍历不就好了,每一层遍历开始时更新一下这一层的节点数量,这样层序遍历结束,这棵树的最大宽度也就知道了。

       但是,这道题中已经说明了如果子节点为null也要计入长度,那么就需要为每个节点进行编号。其中root节点的编号为1,我们假设一个节点的编号为n,那么它的左子节点的编号一定为2*n,右子节点的编号一定为2*n+1。然后,我们根据这个规则对整个二叉树进行重新编号。

        对于示例1中的二叉树,我们对其进行编号后如下图所示,每层的宽度可以使用最左侧的节点编号减去最右侧的节点编号加1,我们可以计算出每一层的宽度,最大的宽度就是4。

        对于示例2中的二叉树,我们对其进行编号后如下图所示,每层的宽度可以也是使用最左侧的节点编号减去最右侧的节点编号加1,我们可以计算出每一层的宽度,最大的宽度就是7。 

         接下来我们可以使用广度优先遍历和深度优先遍历两种不同的方法来求解。

解法一:广度优先遍历

        我们直接套用二叉树层序遍历的思路,在遍历的过程中给每个二叉树节点进行编号,每一层遍历结束后,使用这一层最右侧节点编号减去最左侧节点编号再加1作为这一层的宽度。

lass Solution {
    public int widthOfBinaryTree(TreeNode root) {
        int res = 1;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        root.val = 1;
        while(!queue.isEmpty()) {
            int size = queue.size();
            List<Integer> list = new ArrayList<>();
            for(int i = 0; i < size; i++) {
                TreeNode curNode = queue.poll();
                list.add(curNode.val);
                if (curNode.left != null) {
                    queue.offer(curNode.left);
                    curNode.left.val = curNode.val * 2;
                }
                if (curNode.right != null) {
                    queue.offer(curNode.right);
                    curNode.right.val = curNode.val * 2 + 1;
                }
            }
            res = Math.max(res, list.get(list.size() - 1) - list.get(0) + 1);
        }
        return res;
    }
}

解法二:深度优先遍历

class Solution {
    // 存储结果
    int result = 0;
    // 存储每一层最左侧的节点编号
    Map<Integer, Integer> minValue = new HashMap();
    public int widthOfBinaryTree(TreeNode root) {
        dfs(root, 1, 0);
        return result;
    }

    /**
     * node:当前遍历到的节点
     * nodeIndex:当前节点的编号
     * level:当前节点的层数
     */
    public void dfs(TreeNode node , int nodeIndex, int level) {
        // 结束条件
        if (node == null) return;
        // 存这一层最左侧的节点编号
        minValue.putIfAbsent(level, nodeIndex);
        result = Math.max(result, nodeIndex - minValue.get(level) + 1);
        // 递归
        dfs(node.left, 2 * nodeIndex, level + 1);
        dfs(node.right, 2 * nodeIndex + 1, level + 1);
    }
}

  

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

编程芝士

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

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

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

打赏作者

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

抵扣说明:

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

余额充值