Leetcode 2965.K个元素的最大和

本文最后更新于:2024年6月7日 中午

题目描述

出处

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。你需要执行以下操作 恰好 k 次,最大化你的得分:

  1. nums 中选择一个元素 m
  2. 将选中的元素 m 从数组中删除。
  3. 将新元素 m + 1 添加到数组中。
  4. 你的得分增加 m

请你返回执行以上操作恰好 k 次后的最大得分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
示例 1:
输入:nums = [1,2,3,4,5], k = 3
输出:18
解释:我们需要从 nums 中恰好选择 3 个元素并最大化得分。
第一次选择 5 。和为 5 ,nums = [1,2,3,4,6] 。
第二次选择 6 。和为 6 ,nums = [1,2,3,4,7] 。
第三次选择 7 。和为 5 + 6 + 7 = 18 ,nums = [1,2,3,4,8] 。
所以我们返回 18 。
18 是可以得到的最大答案。

示例 2:
输入:nums = [5,5,5], k = 2
输出:11
解释:我们需要从 nums 中恰好选择 2 个元素并最大化得分。
第一次选择 5 。和为 5 ,nums = [5,5,6] 。
第二次选择 6 。和为 6 ,nums = [5,5,7] 。
所以我们返回 11 。
11 是可以得到的最大答案。

提示:

  • 1 <= nums.length <= 100
  • 1 <= nums[i] <= 100
  • 1 <= k <= 100

解题方法

暴力

直接按照题意模拟 找到nums_\max 并执行kk次删除nums_\max并记录nums_\max的值

首先定义ansans为答案 然后循环模拟

1
2
3
4
5
6
7
8
9
class Solution:
def maximizeSum(self, nums: List[int], k: int) -> int:
ans = 0
for i in range(k):
o = max(nums)
ans+=o
nums.remove(o)
nums.append(o+1)
return ans
  • 时间复杂度:O(k3)时间复杂度:O(k^{3})
  • 空间复杂度:O(1)空间复杂度:O(1) 返回值不计入

数学

首先我们看回题意 可以得知 操作是 找到当前的maxmax值 -> 记录 -> 删除 -> 添加max+1max+1

那么下一次添加的值不就是上一个maxmax值的max+1max+1

因此我们设当前maxmax值为iinums_\max=i

  • 操作第11次 为ii
  • 操作第22次 为i+(i+1)i+(i+1)
  • 操作第33次 为i+(i+1)+(i+1+1)=i+(i+1)+(i+2)i+(i+1)+(i+1+1)=i+(i+1)+(i+2)
  • 操作第44次 为i+(i+1)+(i+1+1)+(i+1+1+1)=i+(i+1)+(i+2)+(i+3)i+(i+1)+(i+1+1)+(i+1+1+1)=i+(i+1)+(i+2)+(i+3)

不难发现 这是一道规律题 得公式

ik+0+1+2+3...+(i1)i*k+0+1+2+3...+(i-1)

问题来了0+1+2+3...+(i1)0+1+2+3...+(i-1)如何算呢 我这里就拿k=4k=4来举例,即1+2+3+41+2+3+4xx为数组的左边界 yy为数组的右边界 即nums[x]+nums[y]=nums[x+1]+nums[y1]nums[x]+nums[y]=nums[x+1]+nums[y-1]

相当于数组的左右两边和是一样的 这样的和可以分为k//2k//2

因此继续推理得到

ik+(k1)(k//2)i*k+(k-1)*(k//2)

kk是奇数的时候 也是按同样的道理 加上它中间哪个数

ik+(k1)(k//2)+(k//2)i*k+(k-1)*(k//2)+(k//2)

最后 得出结论

ans={ik+(k1)(k//2)k/2=0ik+(k1)(k//2)+(k//2)k/2!=0ans=\begin{cases} i*k+(k-1)*(k//2) & k/2=0 \\ i*k+(k-1)*(k//2)+(k//2) & k/2!=0\end{cases}

示例代码

Python

1
2
3
4
5
6
7
8
9
## 时间复杂度O(n)
## 空间复杂度O(1)
class Solution:
def maximizeSum(self, nums: List[int], k: int) -> int:
a = max(nums)
if k % 2 == 0:
return a*k + (k-1) * (k//2)
else:
return a*k + (k-1) * (k//2) + (k//2)

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
int maximizeSum(vector<int>& nums, int k) {
int ans = 0;
for(int i = 0; i < nums.size(); i++){
ans = max(ans,nums[i]);
}
if(k % 2 == 0){
return ans * k + (k-1) * (k/2);
}
return ans * k + (k - 1) * (k/2)+(k/2);
}
};

Leetcode 2965.K个元素的最大和
http://blog.bingyue.top/2023/11/18/leetcode2656/
作者
bingyue
发布于
2023年11月18日
许可协议