• 图解LeetCode——1302. 层数最深叶子节点的和(难度:中等)


    一、题目

    给你一棵二叉树的根节点 root ,请你返回 层数最深的叶子节点的和 。

    二、示例

    2.1> 示例1

    【输入】root = [1,2,3,4,5,null,6,7,null,null,null,null,8]
    【输出】15

    2.2> 示例 2:

    【输入】root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5]
    【输出】19

    提示:

    • 树中节点数目在范围 [1, 104] 之间。
    • 1 <= Node.val <= 100

    三、解题思路

    3.1> 思路1:广度优先算法

    根据题目描述,需要获得层数最深的节点的和,那么既然涉及的是某一层,所以我们会首先想到采用广度优先算法来统计某一层中节点的总和。

    既然确定了要采用广度优先算法来解题,那么我们首先需要一个队列,来存储每层的节点。也就是说,首先我们将root节点放入到队列中,然后开启while的循环,那么只有当队列中是空的情况下,才会结束while循环。那么在while循环中,我们首先将root节点“踢出”队列,然后判断,如果有左子节点,则将左子节点放入到队列中;如果有右子节点,那么同样,也将其放入到队列中;对于没有左子节点或者右子节点的情况,我们不予理会就可以了。

    那么此时有的同学就会有疑问,如果队列中有多个节点呢,你虽然踢出了一个节点,但是将其左右子节点又放入了队列中,那么此时岂不是就包含了两种节点了:

    • 种类一:与被踢出的节点是同一层的节点。
    • 种类二:被踢出的节点的子节点。

    那队列中岂不是混合了两个层的节点了,怎么去区分呢?针对这个问题,我们其实可以再踢出某层第一个节点之前,先计算队列中的节点个数,这样,由于队列是先入先出的,并且是有序的,所以,我们按照提前计算的队列中某层的节点个数,去执行“踢出”操作,就可以解决这个问题了。

    那怎样去判断是最底层的节点呢?既然我们将每层的节点都放到了队列中,那么,如果队列中没有元素了,就代表我们刚刚遍历的就是最底层的节点了。所以,在遍历每一层的时候,我们都需要统计这一层的总和,只是说,每层的总和我们只会使用一个变量int result;当我们计算完第N层的总和只后,我们会直接赋值给result,也就相当于第N层的总和覆盖了第N-1层的总和。

    好了,思路基本讲完了,我们以root = [1,2,3,4,5,6,null,7,null,null,null,null,8]为例,看看具体是怎样操作的。

    首先,我们将root节点放入到队列deque中,然后进入while(!deque.isEmpty())循环中,在循环的逻辑中,我们首先计算deque中元素的个数,其实也就是计算第0层节点的个数,deque.size()等于1,那么我们只需要将Node(1)从队列中“踢出”即可,计算该层总和result=1,并将其左右子节点放入到队列中(即:Node(2)和Node(3))

    上面我们遍历完第0层的节点,我们下面继续遍历第1层的节点。与上面步骤一样,我们首先获得队列中的节点个数,此时节点个数为2(即:Node(2)和Node(3)),也就是表明我们要遍历队列中的2个节点。这时候,我们先将Node(2)踢出队列,并将其左右子节点放入队列中(Node(4)和Node(5)),那么此时队列中包含了3个节点——Node(3)Node(4)Node(5),那么这个情况就是我们上面提到的一个队列中保存了多个层级的节点。由于Node(2)的值为2,所以第1层的节点总和暂时为2;接着我们“踢出”Node(3),将其左子节点Node(6)放入到队列中,由于它没有右子节点,所以不用处理。由于节点Node(3)出队列了,并且Node(6)如队列了,那么此时队列中包含了3个节点——Node(4)Node(5)Node(6),正好是第2层的所有节点。此时,计算第1层总和为2+3=5。具体操作,请见下图:

    对于第2层第3层的操作逻辑,跟上面类似,此处就不赘述了。我们直接看下图的具体操作就可以了:

    针对于广度优先算法的具体代码实现,请参照:1> 实现1:广度优先算法

    4.2> 思路2:深度优先算法

    一般来说,广度优先算法的问题,同样也可以采用了深度优先算法去解答。在深度优先算法的中,我们不再需要队列的支持,只需要遍历maxLevel去记录当前的“最大层次”,为什么是“当前”呢?就是因为我们在深度优先算法中,是以某一条分支去遍历的,所以,当我们发现当前的层数大于了maxLevel的时候,我们就要将maxLevel更新为当前层数,同时重置result属性。

    那么,当我们遍历的叶子节点所在的层数小于maxLevel,那么,恭喜你,我们什么都不需要去做了。如果我们发现当前叶子节点等于maxLevel,那么我们就开始将该节点的val值加到result变量上进行层级节点的统计操作。

    现在,我们还是以root = [1,2,3,4,5,6,null,7,null,null,null,null,8]为例,深度优先算法的具体操作,请参照下图所示:

    针对于深度优先算法的具体代码实现,请参照:2> 实现2:深度优先算法

    四、代码实现

    4.1> 实现1:广度优先算法

    1. class Solution {
    2.     public int deepestLeavesSum(TreeNode root) {
    3.         int result = 0;
    4.         Queue<TreeNode> deque = new ArrayDeque();
    5.         deque.offer(root);
    6.         while(!deque.isEmpty()){
    7.             result = 0;
    8.             int nums = deque.size();
    9.             for(int i = 0; i < nums; i++){
    10.                 TreeNode node = deque.poll();
    11.                 if(node.left != null) deque.offer(node.left);
    12.                 if(node.right != null) deque.offer(node.right);
    13.                 result += node.val;
    14.             }
    15.         }
    16.         return result;
    17.     }
    18. }

    4.2> 实现2:深度优先算法

    1. class Solution {
    2.     int result = 0, maxLevel = 0;
    3.     public int deepestLeavesSum(TreeNode root) {       
    4.         calculate(root, maxLevel);
    5.         return result;
    6.     }
    7.     public void calculate(TreeNode node, int level) {
    8.         if (level > maxLevel) {
    9.             maxLevel = level;
    10.             result = node.val;
    11.         } else if (level == maxLevel) {
    12.             result += node.val;
    13.         } 
    14.         if (node.left != null) calculate(node.left, level + 1);
    15.         if (node.right != null) calculate(node.right, level + 1);
    16.     }
    17. }

    今天的文章内容就这些了:

    写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

    更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

  • 相关阅读:
    uni-app:实现picker下拉列表
    大学生网课搜题公众号如何搭建?
    白炽灯对婴儿眼睛好吗?分享适合婴儿、光线柔和的护眼台灯
    LENOVO联想笔记本小新 Pro-14 2021AMD处理器ACH版(82MS)原厂Win10系统
    使用viewerJs替换fastadmin中表格图片预览功能,实现鼠标缩放旋转等功能
    网络工程师知识点2
    广州华锐互动VRAR:利用VR开展刑事案件公安取证培训,沉浸式体验提升实战能力
    【英语基础篇】新概念一册lesson 3 - sorry,sir
    设计模式-原则篇-01.开闭原则
    MySQL 字段值按照分隔符拆分成列(行转列)
  • 原文地址:https://blog.csdn.net/qq_26470817/article/details/126395648