java数据结构与算法之二叉树的最大宽度和最大深度问题

Posted wen-pan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java数据结构与算法之二叉树的最大宽度和最大深度问题相关的知识,希望对你有一定的参考价值。

①、最大深度问题

  • 求二叉树的最大深度,最常见的无非两种方式
  • 第一种是,以【宽度优先遍历】统计树的层数,树有多少层,那么树就有多高
  • 第二种是,以【深度优先遍历】,以我们上面讲的【二叉树通用套路】,每个节点都可以向他的左右孩子要信息来求解

深度优先求树的最大高度解法

/**
 * 以深度优先,求二叉树的高度
 */
public static int height(TreeNode treeNode) 
    if (treeNode == null) 
        return 0;
    
    // 分别获取到左右孩子的树高度(问左右孩子要信息)
    int left = height(treeNode.left);
    int right = height(treeNode.right);

    // 整合所有孩子的高度,以当前节点为头的二叉树的树高为左右孩子中最高的高度 + 1
    return Math.max(left, right) + 1;

宽度优先求树的最大深度解法

/**
 * 以宽度优先求二叉树的高度
 * 该二叉树有多少层,那么就说明该树有多高,根据这个特性我们就可以使用宽度优先遍历来计算该树的层数,进而求得树的高度
 */
public static int height2(TreeNode treeNode) 
    if (treeNode == null) 
        return 0;
    
    LinkedList<TreeNode> queue = new LinkedList<>();
    HashMap<TreeNode, Integer> levelMap = new HashMap<>();
    // 当前层
    int currentLevel = 1;
    queue.addLast(treeNode);
    levelMap.put(treeNode, 1);

    while (!queue.isEmpty()) 
        TreeNode poll = queue.pollFirst();
        // 节点出现了跨层,那么就把层数++
        if (currentLevel != levelMap.get(poll)) 
            currentLevel++;
        
        // 处理孩子节点
        if (poll.left != null) 
            levelMap.put(poll.left, levelMap.get(poll) + 1);
            queue.addLast(poll.left);
        
        if (poll.right != null) 
            levelMap.put(poll.right, levelMap.get(poll) + 1);
            queue.addLast(poll.right);
        
    

    return currentLevel;

②、最大宽度问题

  • 最大宽度问题,最常使用的解法便是【借助队列】 + BFS,一层一层的遍历二叉树,并且记录好每一层的节点个数,节点个数最多的层,便是该树的最大宽度
  • 通常我们使用的是【hash表 + BFS】来记录下每个节点所处的层数
  • 然后使用BFS宽度优先遍历法,去统计每层的节点个数(每一层的宽度),最宽的那一层便是二叉树的最大宽度
public static int width(TreeNode treeNode) 
    if (treeNode == null) 
        return 0;
    
    //队列
    LinkedList<TreeNode> queue = new LinkedList<>();
    // 存放层级关系的map
    HashMap<TreeNode, Integer> levelMap = new HashMap<>();
    // 树的最大宽度
    int maxWidth = -1;
    // 当前所在的层
    int currentLevel = 1;
    // 当前层的节点数量
    int currentLevelCount = 0;
    queue.addLast(treeNode);
    // 先记录上每个节点所处的层
    levelMap.put(treeNode, 1);

    while (!queue.isEmpty()) 
        TreeNode poll = queue.pollFirst();
        // 节点没有跨层
        if (currentLevel == levelMap.get(poll)) 
            currentLevelCount++;
         else 
            // 遇到第一个跨层的节点,先【结算上一层】节点个数和最大值,然后【重置当前层的节点个数为1个】
            maxWidth = Math.max(maxWidth, currentLevelCount);
            currentLevelCount = 1;
            currentLevel++;
        
        // 左右孩子分别入队列,并记录他们所处的层数
        if (poll.left != null) 
            levelMap.put(poll.left, levelMap.get(poll) + 1);
            queue.addLast(poll.left);
        
        if (poll.right != null) 
            levelMap.put(poll.right, levelMap.get(poll) + 1);
            queue.addLast(poll.right);
        
    

    return maxWidth;

以上是关于java数据结构与算法之二叉树的最大宽度和最大深度问题的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode(104)之二叉树的最大深度

数据结构与算法-求给定二叉树的最大深度

算法题367:二叉树的最大深度

java数据结构与算法之二叉树深度优先和广度优先遍历

二叉树的最小高度,最大高度(深度)和宽度

LeetCode Java刷题笔记—104. 二叉树的最大深度