每日LeetCode —— 1161. 最大层内元素和

201 阅读3分钟

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

题目描述

给定一个二叉树的根节点root,根节点所在的层为第一层,计算每层节点元素的和,返回节点元素和最大所在的层,若多最大和有多层,则返回层次最小的那个;

例1:输入:"[7,2,9,11,null,2,null,null,null,null,13]"  输出:"3"

解释:该输入所对应的图结构如下图

1.png

       第一层的和为7,第二层的和为11,第三层的和为13,第四层的和为13,可见第三层和第四层的和均为最大值13,根据题目的约束,则应该返回层次3.

本题值得注意的地方

  • 节点的数目范围为 1 ~ 1e4
  • 节点值的范围为 -1e5 ~ 1e5

原题地址:1161. 最大层内元素和

解题思路

       层次遍历是本题最先想到的方法,记录当前已经计算过的层次的和以及层次数,当遍历完当前层次后,比较当前层次与之前记录的最大值,若大于最大值,则更新最大值与最大值所在的层次。

       层次遍历用到的数据结构为队列,在出队节点计算节点和的同时将该该节点的左右孩子节点入队,那么该如何判断队列中的节点是否属于同一层呢?这里采用计数的方法,初始时将根节点入队,则此时队列的大小即为 1 ,记录此时的队列大小 m,处理完队头的 m 个元素后,该 m 个节点的下一层所有的节点也都得到了入队,则此时队列中的节点元素全都为该 m 个节点的下一层节点,接着进行上面的操作,直到队列为空,则该二叉树处理完成。

例如处理例1所表示的二叉树

2.png        初始时将根节点入队,则为 queue1 所示,记录当前 queue 的大小 m 即为 1 ,处理队列中前 m 个节点,在处理的过程中计算该 m 个节点的和以及将节点的左右孩子节点也入队,处理完后队列变为 queue2 ,此时队列中剩下2、9,即全为第二层的节点,继续记录当前 queue2 中的节点数 m 为2,继续处理队头的 m 个节点,重复该操作,直到处理完queue4即最后一层,该二叉树处理完成。

实现代码

class Solution {
public:
    int maxLevelSum(TreeNode* root) {
        // 分别记录最大和所在的层、当前遍历到的层、最大和
        int res = 1,curlevel = 1,maxsum = INT_MIN;
        queue<TreeNode*> queue;
        queue.push(root);
        while(queue.size()){
            // 记录当前队列中的所有节点数即该层的所有节点数,初始化该层的和为0
            int m = queue.size(),sum = 0;
            // 处理该层的所有节点
            while(m--){
                auto t = queue.front();
                queue.pop();
                // 处理节点并入队
                if(t->left) queue.push(t->left);
                if(t->right) queue.push(t->right);
                sum += t->val;
            }
            // 比较当前层的元素和是否大于之前层的元素和
            if(sum > maxsum){
                maxsum = sum;
                res = curlevel;
            }
            curlevel++;
        }
        return res;
    }
};