Medium
题目描述
给你一个二叉树的根节点 root 和一个正整数 k。
树中的层和是指在同一层上节点值的总和。
返回树中第 k 大的层和(不需要去重)。如果树的层数小于 k,返回 -1。
注意,如果两个节点与根节点的距离相同,则它们在同一层。
示例 1:
输入:root = [5,8,9,2,1,3,7,4,6], k = 2
输出:13
解释:层和如下:
- 第 1 层:5。
- 第 2 层:8 + 9 = 17。
- 第 3 层:2 + 1 + 3 + 7 = 13。
- 第 4 层:4 + 6 = 10。
第2大的层和是13。
示例 2:
输入:root = [1,2,null,3], k = 1
输出:3
解释:最大的层和是3。
约束条件:
- 树中节点的数目为
n 2 <= n <= 10^51 <= Node.val <= 10^61 <= k <= n
解题思路
这道题需要计算二叉树每层的节点和,然后找到第K大的层和。
核心思路:
层序遍历计算层和:使用BFS(广度优先搜索)逐层遍历二叉树,计算每一层的节点值总和。我们可以用队列来实现层序遍历,每次处理完一层的所有节点后,将它们的子节点加入队列。
排序找第K大:将所有层和存储在数组中,然后对数组进行降序排序,返回第K个元素(索引为k-1)。
边界情况处理:如果树的层数少于k层,返回-1。
实现细节:
- 使用队列进行BFS遍历,每次记录当前层的节点数量
- 对于每一层,计算所有节点值的总和
- 将层和存入数组,最后排序取第k大值
时间复杂度主要来自BFS遍历和排序,空间复杂度主要是队列和层和数组的存储。
代码实现
class Solution {
public:
long long kthLargestLevelSum(TreeNode* root, int k) {
vector<long long> levelSums;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int levelSize = q.size();
long long levelSum = 0;
for (int i = 0; i < levelSize; i++) {
TreeNode* node = q.front();
q.pop();
levelSum += node->val;
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
levelSums.push_back(levelSum);
}
if (levelSums.size() < k) return -1;
sort(levelSums.begin(), levelSums.end(), greater<long long>());
return levelSums[k - 1];
}
};
class Solution:
def kthLargestLevelSum(self, root: Optional[TreeNode], k: int) -> int:
level_sums = []
queue = [root]
while queue:
level_size = len(queue)
level_sum = 0
next_queue = []
for _ in range(level_size):
node = queue.pop(0)
level_sum += node.val
if node.left:
next_queue.append(node.left)
if node.right:
next_queue.append(node.right)
level_sums.append(level_sum)
queue = next_queue
if len(level_sums) < k:
return -1
level_sums.sort(reverse=True)
return level_sums[k - 1]
public class Solution {
public long KthLargestLevelSum(TreeNode root, int k) {
List<long> levelSums = new List<long>();
Queue<TreeNode> queue = new Queue<TreeNode>();
queue.Enqueue(root);
while (queue.Count > 0) {
int levelSize = queue.Count;
long levelSum = 0;
for (int i = 0; i < levelSize; i++) {
TreeNode node = queue.Dequeue();
levelSum += node.val;
if (node.left != null) queue.Enqueue(node.left);
if (node.right != null) queue.Enqueue(node.right);
}
levelSums.Add(levelSum);
}
if (levelSums.Count < k) return -1;
levelSums.Sort((a, b) => b.CompareTo(a));
return levelSums[k - 1];
}
}
var kthLargestLevelSum = function(root, k) {
const levelSums = [];
const queue = [root];
while (queue.length > 0) {
const levelSize = queue.length;
let levelSum = 0;
for (let i = 0; i < levelSize; i++) {
const node = queue.shift();
levelSum += node.val;
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
levelSums.push(levelSum);
}
if (levelSums.length < k) return -1;
levelSums.sort((a, b) => b - a);
return levelSums[k - 1];
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n + h log h) | n为节点数(BFS遍历),h为树的高度(排序层和数组) |
| 空间复杂度 | O(w + h) | w为树的最大宽度(队列空间),h为树的高度(层和数组) |