
题目描述
给你一个长度为 n 的数组 happiness ,以及一个 正整数 k 。
n 个孩子站成一队,其中第 i 个孩子的 幸福值 是 happiness[i] 。你计划组织 k 轮筛选从这 n 个孩子中选出 k 个孩子。
在每一轮选择一个孩子时,所有 尚未 被选中的孩子的 幸福值 将减少 1 。注意,幸福值 不能 变成负数,且只有在它是正数的情况下才会减少。
选择 k 个孩子,并使你选中的孩子幸福值之和最大,返回你能够得到的 最大值 。
示例 1:
输入:happiness = [1,2,3], k = 2
输出:4
解释:按以下方式选择 2 个孩子:
- 选择幸福值为 3 的孩子。剩余孩子的幸福值变为 [0,1] 。
- 选择幸福值为 1 的孩子。剩余孩子的幸福值变为 [0] 。注意幸福值不能小于 0 。
所选孩子的幸福值之和为 3 + 1 = 4 。
示例 2:
输入:happiness = [1,1,1,1], k = 2
输出:1
解释:按以下方式选择 2 个孩子:
- 选择幸福值为 1 的任意一个孩子。剩余孩子的幸福值变为 [0,0,0] 。
- 选择幸福值为 0 的孩子。剩余孩子的幸福值变为 [0,0] 。
所选孩子的幸福值之和为 1 + 0 = 1 。
示例 3:
输入:happiness = [2,3,4,5], k = 1
输出:5
解释:按以下方式选择 1 个孩子:
- 选择幸福值为 5 的孩子。剩余孩子的幸福值变为 [1,2,3] 。
所选孩子的幸福值之和为 5 。
提示:
1 <= n == happiness.length <= 2 * 105 1 <= happiness[i] <= 108 1 <= k <= n
解法
方法一:贪心 + 排序
为了使得幸福值之和尽可能大,我们应该优先选择幸福值大的孩子。因此,我们可以对孩子按照幸福值从大到小排序,然后依次选择 \(k\) 个孩子。对于当前第 \(i\) 个孩子,能够得到的幸福值为 \(\max(\textit{happiness}[i] - i, 0)\),最后返回这 \(k\) 个孩子的幸福值之和。
时间复杂度 \(O(n \times \log n + k)\),空间复杂度 \(O(\log n)\)。其中 \(n\) 是数组 \(\textit{happiness}\) 的长度。
| class Solution:
def maximumHappinessSum(self, happiness: List[int], k: int) -> int:
happiness.sort(reverse=True)
ans = 0
for i, x in enumerate(happiness[:k]):
x -= i
ans += max(x, 0)
return ans
|
| class Solution {
public long maximumHappinessSum(int[] happiness, int k) {
Arrays.sort(happiness);
long ans = 0;
for (int i = 0, n = happiness.length; i < k; ++i) {
int x = happiness[n - i - 1] - i;
ans += Math.max(x, 0);
}
return ans;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12 | class Solution {
public:
long long maximumHappinessSum(vector<int>& happiness, int k) {
sort(happiness.rbegin(), happiness.rend());
long long ans = 0;
for (int i = 0, n = happiness.size(); i < k; ++i) {
int x = happiness[i] - i;
ans += max(x, 0);
}
return ans;
}
};
|
| func maximumHappinessSum(happiness []int, k int) (ans int64) {
sort.Ints(happiness)
for i := 0; i < k; i++ {
x := happiness[len(happiness)-i-1] - i
ans += int64(max(x, 0))
}
return
}
|
| function maximumHappinessSum(happiness: number[], k: number): number {
happiness.sort((a, b) => b - a);
let ans = 0;
for (let i = 0; i < k; ++i) {
const x = happiness[i] - i;
ans += Math.max(x, 0);
}
return ans;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | impl Solution {
pub fn maximum_happiness_sum(mut happiness: Vec<i32>, k: i32) -> i64 {
happiness.sort_unstable_by(|a, b| b.cmp(a));
let mut ans: i64 = 0;
for i in 0..(k as usize) {
let x = happiness[i] as i64 - i as i64;
if x > 0 {
ans += x;
}
}
ans
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | public class Solution {
public long MaximumHappinessSum(int[] happiness, int k) {
Array.Sort(happiness, (a, b) => b.CompareTo(a));
long ans = 0;
for (int i = 0; i < k; i++) {
int x = happiness[i] - i;
if (x <= 0) {
break;
}
ans += x;
}
return ans;
}
}
|