本文最后更新于:2024年6月7日 中午
题目描述
出处
给你一个下标从 0 开始的整数数组 nums
和一个整数 k
。你需要执行以下操作 恰好 k
次,最大化你的得分:
从 nums
中选择一个元素 m
。
将选中的元素 m
从数组中删除。
将新元素 m + 1
添加到数组中。
你的得分增加 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 并执行k k k 次删除nums_\max 并记录nums_\max 的值
首先定义a n s ans an s 为答案 然后循环模拟
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 ( k 3 ) 时间复杂度:O(k^{3}) 时间复杂度 : O ( k 3 )
空间复杂度 : O ( 1 ) 空间复杂度:O(1) 空间复杂度 : O ( 1 ) 返回值不计入
数学
首先我们看回题意 可以得知 操作是 找到当前的m a x max ma x 值 -> 记录 -> 删除 -> 添加m a x + 1 max+1 ma x + 1
那么下一次添加的值不就是上一个m a x max ma x 值的m a x + 1 max+1 ma x + 1
因此我们设当前m a x max ma x 值为i i i 即nums_\max=i
操作第1 1 1 次 为i i i
操作第2 2 2 次 为i + ( i + 1 ) i+(i+1) i + ( i + 1 )
操作第3 3 3 次 为i + ( i + 1 ) + ( i + 1 + 1 ) = i + ( i + 1 ) + ( i + 2 ) i+(i+1)+(i+1+1)=i+(i+1)+(i+2) i + ( i + 1 ) + ( i + 1 + 1 ) = i + ( i + 1 ) + ( i + 2 )
操作第4 4 4 次 为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) i + ( i + 1 ) + ( i + 1 + 1 ) + ( i + 1 + 1 + 1 ) = i + ( i + 1 ) + ( i + 2 ) + ( i + 3 )
不难发现 这是一道规律题 得公式
i ∗ k + 0 + 1 + 2 + 3... + ( i − 1 ) i*k+0+1+2+3...+(i-1)
i ∗ k + 0 + 1 + 2 + 3... + ( i − 1 )
问题来了0 + 1 + 2 + 3... + ( i − 1 ) 0+1+2+3...+(i-1) 0 + 1 + 2 + 3... + ( i − 1 ) 如何算呢 我这里就拿k = 4 k=4 k = 4 来举例,即1 + 2 + 3 + 4 1+2+3+4 1 + 2 + 3 + 4 设x x x 为数组的左边界 y y y 为数组的右边界 即n u m s [ x ] + n u m s [ y ] = n u m s [ x + 1 ] + n u m s [ y − 1 ] nums[x]+nums[y]=nums[x+1]+nums[y-1] n u m s [ x ] + n u m s [ y ] = n u m s [ x + 1 ] + n u m s [ y − 1 ]
相当于数组的左右两边和是一样的 这样的和可以分为k / / 2 k//2 k //2 组
因此继续推理得到
i ∗ k + ( k − 1 ) ∗ ( k / / 2 ) i*k+(k-1)*(k//2)
i ∗ k + ( k − 1 ) ∗ ( k //2 )
当k k k 是奇数的时候 也是按同样的道理 加上它中间哪个数
i ∗ k + ( k − 1 ) ∗ ( k / / 2 ) + ( k / / 2 ) i*k+(k-1)*(k//2)+(k//2)
i ∗ k + ( k − 1 ) ∗ ( k //2 ) + ( k //2 )
最后 得出结论
a n s = { i ∗ k + ( k − 1 ) ∗ ( k / / 2 ) k / 2 = 0 i ∗ k + ( k − 1 ) ∗ ( k / / 2 ) + ( k / / 2 ) k / 2 ! = 0 ans=\begin{cases} i*k+(k-1)*(k//2) & k/2=0 \\ i*k+(k-1)*(k//2)+(k//2) & k/2!=0\end{cases}
an s = { i ∗ k + ( k − 1 ) ∗ ( k //2 ) i ∗ k + ( k − 1 ) ∗ ( k //2 ) + ( k //2 ) k /2 = 0 k /2 ! = 0
示例代码
Python
1 2 3 4 5 6 7 8 9 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 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 ); } };