持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
题目链接:1161. 最大层内元素和
题目描述
给你一个二叉树的根节点 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)
解题思路分析
该题为二叉树层序遍历的典型题目:
- 我们可以采用
BFS广度优先搜索来实现二叉树的层序遍历,维护最大层数和答案即可; - 也可以使用
DFS深度优先搜索来完成二叉树的遍历,在遍历的过程中记录当前层数,将当前元素加到对应层数中去即可,最后取元素和最大的那一层即可,如果有多个,返回最小的一层。
具体实现
由于题目要求计算的是每层的元素之和,用广度优先搜索来层序遍历这棵树会更加符合题意。
- 采用队列来实现
BFS的层序遍历; - 最开始将根节点压入队列;然后每次取出的元素个数为当前队列的元素个数,将子节点继续入队,直到队列为空。
- 期间用多个变量来记录和维护答案层数、当前层数的元素和以及当前层数。
复杂度分析
- 时间复杂度:,其中
n是二叉树的节点个数。 - 空间复杂度:。最坏情况下,队列中有
n个节点。
代码实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxLevelSum(TreeNode* root) {
// ans 记录最大和的层数
int ans = 0;
// 初始化最大和 m 为最小值 INT_MIN,k 记录当前层数
int m = INT_MIN, k = 1;
queue<TreeNode*> que;
while(que.size()) que.pop();
// 从根节点开始层序遍历
que.push(root);
while(que.size()){
// n 为当前层元素个数
int n = que.size();
// temp 记录当前层的和
int temp = 0;
for(int i = 0; i < n; i++){
TreeNode* now = que.front();
que.pop();
// 记录当前层元素和
temp += now->val;
// 将下一层元素放入队列
if(now->left) que.push(now->left);
if(now->right) que.push(now->right);
}
// 如果大于最大和 m 就更新答案和维护 m 的值
if(temp > m){
ans = k;
m = temp;
}
// 层数+1
k++;
}
return ans;
}
};
总结
- 遇到图和树的题八成都是需要遍历的,根据题意来选择
DFS深度优先搜索和BFS广度优先搜索。 - 该题求的是每一层的元素和,满足
BFS广度优先搜索的模型。 - 注意在代码实现中需要注意队列初始化清空,以及每次处理队头元素后记得弹出队头元素。
- 测试结果:
结束语
人生不简单,尽量简单过。不愿接受,那就改变;不能改变,就试着放下。生命是属于自己的,要让自己开心,把时间留给值得托付的人。愿你心中藏着善良,眼里带着光芒,活成自己想要的样子。新的一天,加油!