LeetCode 3462: Maximum Sum With at Most K Elements (Row Limits + Global Greedy)
LeetCode 3462GreedySortingToday we solve LeetCode 3462 - Maximum Sum With at Most K Elements.
Source: https://leetcode.com/problems/maximum-sum-with-at-most-k-elements/
English
Problem Summary
We have a matrix grid, a per-row pick cap array limits, and an integer k. We can select at most limits[i] numbers from row i, and at most k numbers total. Return the maximum possible sum.
Key Insight
For each row, only its largest limits[i] elements can ever help the optimal answer. Collect these candidates from every row, then globally take the largest k values.
Algorithm
- Sort each row in descending order.
- Push the first min(limits[i], rowLen) elements into a global candidate list.
- Sort candidates descending.
- Sum the first min(k, candidates.size()) values.
Complexity Analysis
Let total cell count be N, and let M be candidate count after row limits.
Time: O(N log C + M log M) where C is average row length (or row-wise sort sum).
Space: O(M).
Common Pitfalls
- Forgetting row caps, directly taking global top k from all cells.
- Not guarding when limits[i] exceeds row length.
- Using int for sum when values can require long.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public long maxSum(int[][] grid, int[] limits, int k) {
java.util.List<Integer> candidates = new java.util.ArrayList<>();
for (int i = 0; i < grid.length; i++) {
int[] row = grid[i];
java.util.Arrays.sort(row);
int take = Math.min(limits[i], row.length);
for (int t = 0; t < take; t++) {
candidates.add(row[row.length - 1 - t]);
}
}
candidates.sort(java.util.Collections.reverseOrder());
long ans = 0L;
for (int i = 0; i < Math.min(k, candidates.size()); i++) {
ans += candidates.get(i);
}
return ans;
}
}import "sort"
func maxSum(grid [][]int, limits []int, k int) int64 {
candidates := make([]int, 0)
for i, row := range grid {
sort.Ints(row)
take := limits[i]
if take > len(row) {
take = len(row)
}
for t := 0; t < take; t++ {
candidates = append(candidates, row[len(row)-1-t])
}
}
sort.Slice(candidates, func(i, j int) bool { return candidates[i] > candidates[j] })
if k > len(candidates) {
k = len(candidates)
}
var ans int64
for i := 0; i < k; i++ {
ans += int64(candidates[i])
}
return ans
}class Solution {
public:
long long maxSum(vector<vector<int>>& grid, vector<int>& limits, int k) {
vector<int> candidates;
for (int i = 0; i < (int)grid.size(); i++) {
auto& row = grid[i];
sort(row.begin(), row.end());
int take = min(limits[i], (int)row.size());
for (int t = 0; t < take; t++) {
candidates.push_back(row[(int)row.size() - 1 - t]);
}
}
sort(candidates.begin(), candidates.end(), greater<int>());
long long ans = 0;
for (int i = 0; i < min(k, (int)candidates.size()); i++) {
ans += candidates[i];
}
return ans;
}
};class Solution:
def maxSum(self, grid: list[list[int]], limits: list[int], k: int) -> int:
candidates = []
for i, row in enumerate(grid):
row.sort(reverse=True)
candidates.extend(row[:limits[i]])
candidates.sort(reverse=True)
return sum(candidates[:k])var maxSum = function(grid, limits, k) {
const candidates = [];
for (let i = 0; i < grid.length; i++) {
const row = grid[i].slice().sort((a, b) => b - a);
const take = Math.min(limits[i], row.length);
for (let t = 0; t < take; t++) {
candidates.push(row[t]);
}
}
candidates.sort((a, b) => b - a);
let ans = 0;
for (let i = 0; i < Math.min(k, candidates.length); i++) {
ans += candidates[i];
}
return ans;
};中文
题目概述
给定矩阵 grid、每一行最多可选数量 limits,以及总可选数量上限 k。每行最多选 limits[i] 个元素,总共最多选 k 个元素,求最大和。
核心思路
对于每一行,真正有价值的只可能是该行最大的前 limits[i] 个数。先把这些候选收集起来,再在全局中取最大的前 k 个即可。
算法步骤
- 每行降序处理(或升序后从尾部取)。
- 取该行前 min(limits[i], 行长度) 个候选加入全局数组。
- 将全局候选降序排序。
- 累加前 min(k, 候选数) 个元素。
复杂度分析
设矩阵元素总数为 N,候选总数为 M。
时间复杂度:O(N log C + M log M)(按行排序求和形式)。
空间复杂度:O(M)。
常见陷阱
- 忽略每行上限,直接在全矩阵里选全局前 k。
- limits[i] 大于行长度时未做裁剪。
- 累加和可能溢出,需用 long/long long。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public long maxSum(int[][] grid, int[] limits, int k) {
java.util.List<Integer> candidates = new java.util.ArrayList<>();
for (int i = 0; i < grid.length; i++) {
int[] row = grid[i];
java.util.Arrays.sort(row);
int take = Math.min(limits[i], row.length);
for (int t = 0; t < take; t++) {
candidates.add(row[row.length - 1 - t]);
}
}
candidates.sort(java.util.Collections.reverseOrder());
long ans = 0L;
for (int i = 0; i < Math.min(k, candidates.size()); i++) {
ans += candidates.get(i);
}
return ans;
}
}import "sort"
func maxSum(grid [][]int, limits []int, k int) int64 {
candidates := make([]int, 0)
for i, row := range grid {
sort.Ints(row)
take := limits[i]
if take > len(row) {
take = len(row)
}
for t := 0; t < take; t++ {
candidates = append(candidates, row[len(row)-1-t])
}
}
sort.Slice(candidates, func(i, j int) bool { return candidates[i] > candidates[j] })
if k > len(candidates) {
k = len(candidates)
}
var ans int64
for i := 0; i < k; i++ {
ans += int64(candidates[i])
}
return ans
}class Solution {
public:
long long maxSum(vector<vector<int>>& grid, vector<int>& limits, int k) {
vector<int> candidates;
for (int i = 0; i < (int)grid.size(); i++) {
auto& row = grid[i];
sort(row.begin(), row.end());
int take = min(limits[i], (int)row.size());
for (int t = 0; t < take; t++) {
candidates.push_back(row[(int)row.size() - 1 - t]);
}
}
sort(candidates.begin(), candidates.end(), greater<int>());
long long ans = 0;
for (int i = 0; i < min(k, (int)candidates.size()); i++) {
ans += candidates[i];
}
return ans;
}
};class Solution:
def maxSum(self, grid: list[list[int]], limits: list[int], k: int) -> int:
candidates = []
for i, row in enumerate(grid):
row.sort(reverse=True)
candidates.extend(row[:limits[i]])
candidates.sort(reverse=True)
return sum(candidates[:k])var maxSum = function(grid, limits, k) {
const candidates = [];
for (let i = 0; i < grid.length; i++) {
const row = grid[i].slice().sort((a, b) => b - a);
const take = Math.min(limits[i], row.length);
for (let t = 0; t < take; t++) {
candidates.push(row[t]);
}
}
candidates.sort((a, b) => b - a);
let ans = 0;
for (let i = 0; i < Math.min(k, candidates.length); i++) {
ans += candidates[i];
}
return ans;
};
Comments