leetcode
leetcode 2301 ~ 2350
K 个元素的最大和

K 个元素的最大和

难度:

标签:

题目描述

You are given a 0-indexed integer array nums and an integer k. Your task is to perform the following operation exactly k times in order to maximize your score:

  1. Select an element m from nums.
  2. Remove the selected element m from the array.
  3. Add a new element with a value of m + 1 to the array.
  4. Increase your score by m.

Return the maximum score you can achieve after performing the operation exactly k times.

 

Example 1:

Input: nums = [1,2,3,4,5], k = 3
Output: 18
Explanation: We need to choose exactly 3 elements from nums to maximize the sum.
For the first iteration, we choose 5. Then sum is 5 and nums = [1,2,3,4,6]
For the second iteration, we choose 6. Then sum is 5 + 6 and nums = [1,2,3,4,7]
For the third iteration, we choose 7. Then sum is 5 + 6 + 7 = 18 and nums = [1,2,3,4,8]
So, we will return 18.
It can be proven, that 18 is the maximum answer that we can achieve.

Example 2:

Input: nums = [5,5,5], k = 2
Output: 11
Explanation: We need to choose exactly 2 elements from nums to maximize the sum.
For the first iteration, we choose 5. Then sum is 5 and nums = [5,5,6]
For the second iteration, we choose 6. Then sum is 5 + 6 = 11 and nums = [5,5,7]
So, we will return 11.
It can be proven, that 11 is the maximum answer that we can achieve.

 

Constraints:

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

 

代码结果

运行时间: 26 ms, 内存: 16.0 MB


/*
 * 思路:
 * 使用Java Stream进行处理
 * 1. 将数组转为一个优先队列进行操作。
 * 2. 每次选择最大的元素,删除并将其加1的新值加入队列。
 * 3. 将选择的元素值累加到得分中。
 */
import java.util.PriorityQueue;
import java.util.Collections;
import java.util.stream.IntStream;

public class MaximizeScoreStream {
    public int maximizeScore(int[] nums, int k) {
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
        IntStream.of(nums).forEach(maxHeap::offer);
        return IntStream.range(0, k)
                        .map(i -> {
                            int max = maxHeap.poll();
                            maxHeap.offer(max + 1);
                            return max;
                        })
                        .sum();
    }
}

解释

方法:

题解的整体思路是首先找到数组中的最大值,然后假设每次操作都选择这个最大值进行+1操作,以此来最大化得分。总得分由两部分组成:一部分是k次操作中,每次添加的原最大值之和,即max(nums) * k;另一部分是由于每次操作元素+1带来的额外增加的总和,这部分可以通过求前k个自然数之和得到,即k*(k-1)/2。这种策略假设每次都能顺利地找到当前数组中的最大值并进行操作,忽略了实际操作中数组动态变化带来的复杂性。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
题解中假设每次操作都能选择最大值进行增加,但实际操作中删除元素后如何保证每次都能选到最大值?
题解中的假设确实简化了问题,没有考虑到操作过程中数组的动态变化。在实际应用中,每次操作后需要重新计算当前数组的最大值,这可能需要额外的数据结构支持,如最大堆(优先队列),以便快速检索并更新最大值。如果不使用这样的数据结构,每次操作后都需要遍历数组来找到新的最大值,这会增加计算的复杂性和时间成本。
🦆
题解中提到的算法是否考虑了数组中最大值可能不止一个的情况?
题解中确实没有明确说明如何处理数组中最大值不止一个的情况。在实际操作中,如果有多个最大值,选择任意一个进行操作通常不会影响最终得分的最大化,因为每次操作的结果是相同的。然而,这需要在实现时注意,确保算法能够处理这种情况,特别是在使用数据结构如最大堆时,需要确保可以正确处理多个相同的最大值。
🦆
在题解的逻辑中,每次增加的元素总是`m+1`,这是否意味着数组的最大值会连续增加?如果是,如何处理这种连续增加对数组的影响?
是的,按照题解的逻辑,如果每次都选择最大值进行操作,那么数组的最大值将会连续增加。这种连续增加的最大值会使得数组的范围扩大,可能导致需要更大的空间来存储增加的值。在实际处理中,这种情况需要确保数组或使用的数据结构(如最大堆)能够适应这种变化,同时也要注意整个数组的平衡和性能可能受到这种连续增加的影响。具体来说,最大堆将会频繁更新其根节点,这可能导致频繁的堆调整操作。

相关问题