最大层内元素和

868 阅读1分钟

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

一、题目

LeetCode 最大层内元素和

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

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

示例 1:

输入: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

二、题解

给定有一颗二叉树,从根节点往下按层级统计每一层的节点元素值之和,返回节点元素和最大并且层级最小的那一层。

方法一

需要按层计算层节点元素和,那么可以通过深度优先搜索dfs来遍历二叉树,首先需要dfs递归遍历二叉树的所有元素节点,同时遍历过程中需要记得当前的层级,这里用level表示当前的层级号,初始的从0开始即根节点。然后遍历过程中需要一个数组统计每一层的元素之和。如果是新的一层就直接记录当前节点值,否则就累加上之前层的元素和。然后继续遍历左右子树的节点。最后遍历结束时数组中记录的每一层的节点元素之和,只需要遍历数组,计算元素和最大的那一层的层级号即可,最后返回的层级号需要加一。

方法二 同样的按层统计元素和,也可以使用广度优先搜索bfs来遍历二叉树,首先bfs遍历过程中需要一个队列来辅助遍历,队列中记录每一层的节点,然后统计层节点和,最后返回最大层节点和的层级即可。

三、代码

方法一 Java代码

class Solution {
    private List<Integer> levelSum = new ArrayList<Integer>();

    public int maxLevelSum(TreeNode root) {
        dfs(root, 0);
        int ans = 0;
        for (int i = 0; i < levelSum.size(); ++i) {
            if (levelSum.get(i) > levelSum.get(ans)) {
                ans = i;
            }
        }
        return ans + 1;
    }

    private void dfs(TreeNode node, int level) {
        if (node == null) {
            return;
        }
        if (level == levelSum.size()) {
            levelSum.add(node.val);
        } else {
            levelSum.set(level, levelSum.get(level) + node.val);
        }
        dfs(node.left, level + 1);
        dfs(node.right, level + 1);
    }
}

时间复杂度:O(n),递归遍历一次二叉树的节点。

空间复杂度:O(n),需要一个数组记录以及递归消耗栈空间。


方法二 Java代码

class Solution {
    public int maxLevelSum(TreeNode root) {
        int target = 1;
        int curLevel = 0;
        int ans = Integer.MIN_VALUE;
        Deque<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int curSize = queue.size();
            int curAns = 0;
            curLevel++;
            for (int i = 0; i < curSize; i++) {
                TreeNode curNode = queue.poll();
                curAns += curNode.val;
                if (curNode.left != null) {
                    queue.offer(curNode.left);
                }
                if (curNode.right != null) {
                    queue.offer(curNode.right);
                }
            }
            if (curAns > ans) {
                target = curLevel;
                ans = curAns;
            }
        }
        return target;
    }
}

时间复杂度:O(n),递归遍历一次二叉树的节点。

空间复杂度:O(n),需要一个队列辅助遍历。