最大子序列的分数
难度:
标签:
题目描述
You are given two 0-indexed integer arrays nums1
and nums2
of equal length n
and a positive integer k
. You must choose a subsequence of indices from nums1
of length k
.
For chosen indices i0
, i1
, ..., ik - 1
, your score is defined as:
- The sum of the selected elements from
nums1
multiplied with the minimum of the selected elements fromnums2
. - It can defined simply as:
(nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] , nums2[i1], ... ,nums2[ik - 1])
.
Return the maximum possible score.
A subsequence of indices of an array is a set that can be derived from the set {0, 1, ..., n-1}
by deleting some or no elements.
Example 1:
Input: nums1 = [1,3,3,2], nums2 = [2,1,3,4], k = 3 Output: 12 Explanation: The four possible subsequence scores are: - We choose the indices 0, 1, and 2 with score = (1+3+3) * min(2,1,3) = 7. - We choose the indices 0, 1, and 3 with score = (1+3+2) * min(2,1,4) = 6. - We choose the indices 0, 2, and 3 with score = (1+3+2) * min(2,3,4) = 12. - We choose the indices 1, 2, and 3 with score = (3+3+2) * min(1,3,4) = 8. Therefore, we return the max score, which is 12.
Example 2:
Input: nums1 = [4,2,3,1,1], nums2 = [7,5,10,9,6], k = 1 Output: 30 Explanation: Choosing index 2 is optimal: nums1[2] * nums2[2] = 3 * 10 = 30 is the maximum possible score.
Constraints:
n == nums1.length == nums2.length
1 <= n <= 105
0 <= nums1[i], nums2[j] <= 105
1 <= k <= n
代码结果
运行时间: 137 ms, 内存: 34.4 MB
/*
思路:
1. 使用Stream来处理数组操作。
2. 通过Stream找到所有可能的子序列分数,最后返回最大值。
*/
import java.util.stream.IntStream;
import java.util.PriorityQueue;
import java.util.stream.Collectors;
public class SolutionStream {
public int maxScore(int[] nums1, int[] nums2, int k) {
int n = nums1.length;
return IntStream.range(0, n)
.boxed()
.sorted((a, b) -> nums2[b] - nums2[a])
.limit(k)
.collect(Collectors.toList())
.stream()
.mapToInt(i -> nums1[i])
.sum() * IntStream.range(0, n).map(i -> nums2[i]).min().orElse(0);
}
}
解释
方法:
题解的核心思路基于排序和贪心算法。首先,将数组 nums1 和 nums2 基于 nums2 的值进行排序。排序之后,对于每一个可能的最小值(即 nums2 中的元素),选择在这个最小值之后的 K 个 nums1 元素的最大可能和。这是通过使用一个最小堆(优先队列)来维护当前的最大 K 个元素来实现的。随着从后向前遍历排序后的数组,我们更新当前的和并检查是否可以通过替换堆中最小的元素来获得更大的值。这样可以保证每一步都使用了当前最小值之后的 K 个最大值来计算分数。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在题解中选择将数组nums1和nums2基于nums2的值进行排序?这种排序的依据是什么?
▷🦆
在使用最小堆维护K个最大元素时,如何确保堆中始终保持的是K个最大值而不是任意K个值?
▷🦆
题解中提到,从后向前遍历数组并更新当前和,这种从后向前的遍历方式有什么特殊的优势吗?
▷