leetcode刷题日记-【1161. 最大层内元素和】

94 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

题目描述

给你一个二叉树的根节点 root。设根节点位于二叉树的第 1 层,而根节点的子节点位于第 2 层,依此类推。

请返回层内元素之和 最大 的那几层(可能只有一层)的层号,并返回其中 最小 的那个。

 

示例 1:

image.png

输入:root = [1,7,0,7,-8,null,null] 输出:2 解释: 第 1 层各元素之和为 1, 第 2 层各元素之和为 7 + 0 = 7, 第 3 层各元素之和为 7 + -8 = -1, 所以我们返回第 2 层的层号,它的层内元素之和最大。 示例 2:

输入:root = [989,null,10250,98693,-89388,null,null,null,-32127] 输出:2  

提示:

树中的节点数在 [1, 104]范围内 -105 <= Node.val <= 105

题目元素

  • 给定一个二叉树,获取层中树累加和最大的层数,返回最小的层数
  • 意即需要计算每一层的和,然后找出最大和和第一次出现最大和的层数(从上往下遍历)

解题思路

要对二叉树每一层进行累加计算有两种遍历方式,深度优先和广度优先

  • 深度优先 在进行累加时只记录当前层数和当前累加数,累加完成之后,再统计最大值
  • 广度优先 在进行累加时按照层级累加,一次计算完毕当前层的累加数。边遍历边计算最大值

深度优先代码实现

public int maxLevelSum(TreeNode root) {
    // 存储节点对应的累加数 下标是层数,值是层数累加数
    List<Integer> nodeCount = new ArrayList<>();
    countByNode(root, 0, nodeCount);
    // 遍历存储的数组,获取最大值
    int maxNum = Integer.MIN_VALUE;
    int level = 0;
    for (int i = 0;i < nodeCount.size() ; i ++) {
        Integer sum = nodeCount.get(i);
        if (sum > maxNum){
            maxNum = sum;
            level = i;
        }
    }
    return ++level;
}

/**
 * 计算当前节点累加和
 * @param node 当前节点
 * @param nodeNum 当前遍历的层数
 * @param nodeCount 存放值的数组
 * @return 最大层数
 */
private void countByNode(TreeNode node,Integer nodeNum, List<Integer> nodeCount) {
    if (nodeNum == nodeCount.size()){
        nodeCount.add(node.val);
    }else {
        // 计算累加和
        nodeCount.set(nodeNum,nodeCount.get(nodeNum) == null ? nodeCount.get(nodeNum) : nodeCount.get(nodeNum) + node.val);
    }
    if (node.right != null){
        countByNode(node.right, nodeNum + 1, nodeCount);
    }
    if (node.left != null){
        countByNode(node.left, nodeNum + 1, nodeCount);
    }
}

广度优先代码实现

public int maxLevelSum(TreeNode root) {
    // 广度优先 边遍历边对节点层数及节点进行存储
    // 下表是节点层数,值是所属层数的所有节点
    List<TreeNode> treeNodes = new ArrayList<>();
    treeNodes.add(root);
    int maxNum = Integer.MIN_VALUE;
    // 遍历全部层级
    return countByLevel(treeNodes,maxNum,1,1);
}

/**
 * 计算每层的和,及设置最大层数和
 * @param treeNodes
 * @param maxNum
 * @param maxLevel 最大层数和所在的层数
 * @param nowLevel 当前层数
 */
private int countByLevel(List<TreeNode> treeNodes, int maxNum,int maxLevel,int nowLevel) {
    // 遍历当前节点的数值
    int sum = 0;
    List<TreeNode> newNodeList = new ArrayList<>();
    for (int i = 0;i < treeNodes.size();i++){
        sum += treeNodes.get(i).val;
        // 将当前节点的左右节点装入新的数组中
        if (treeNodes.get(i).left != null){
            newNodeList.add(treeNodes.get(i).left);
        }
        if (treeNodes.get(i).right != null){
            newNodeList.add(treeNodes.get(i).right);
        }
    }
    if (sum > maxNum){
        maxNum = sum;
        maxLevel = nowLevel;
    }
    if (newNodeList.isEmpty()){
        return maxLevel;
    }
    return countByLevel(newNodeList,maxNum,maxLevel,++nowLevel);
}