几乎唯一子数组的最大和
难度:
标签:
题目描述
You are given an integer array nums
and two positive integers m
and k
.
Return the maximum sum out of all almost unique subarrays of length k
of nums
. If no such subarray exists, return 0
.
A subarray of nums
is almost unique if it contains at least m
distinct elements.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: nums = [2,6,7,3,1,7], m = 3, k = 4
Output: 18
Explanation: There are 3 almost unique subarrays of size k = 4
. These subarrays are [2, 6, 7, 3], [6, 7, 3, 1], and [7, 3, 1, 7]. Among these subarrays, the one with the maximum sum is [2, 6, 7, 3] which has a sum of 18.
Example 2:
Input: nums = [5,9,9,2,4,5,4], m = 1, k = 3 Output: 23 Explanation: There are 5 almost unique subarrays of size k. These subarrays are [5, 9, 9], [9, 9, 2], [9, 2, 4], [2, 4, 5], and [4, 5, 4]. Among these subarrays, the one with the maximum sum is [5, 9, 9] which has a sum of 23.
Example 3:
Input: nums = [1,2,1,2,1,2,1], m = 3, k = 3 Output: 0 Explanation: There are no subarrays of sizek = 3
that contain at leastm = 3
distinct elements in the given array [1,2,1,2,1,2,1]. Therefore, no almost unique subarrays exist, and the maximum sum is 0.
Constraints:
1 <= nums.length <= 2 * 104
1 <= m <= k <= nums.length
1 <= nums[i] <= 109
代码结果
运行时间: 129 ms, 内存: 19.1 MB
/*
* 思路:
* 使用Java Stream API来处理这个问题。
* 我们可以利用Stream对数组进行滑动窗口操作,然后对每个窗口进行处理。
* 使用HashSet来判断不同元素的数量并计算窗口的和。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int maxSumOfAlmostUniqueSubarray(int[] nums, int m, int k) {
return IntStream.range(0, nums.length - k + 1)
.map(i -> {
Set<Integer> uniqueElements = new HashSet<>();
int currentSum = IntStream.range(i, i + k)
.peek(j -> uniqueElements.add(nums[j]))
.map(j -> nums[j])
.sum();
return uniqueElements.size() >= m ? currentSum : 0;
})
.max()
.orElse(0);
}
}
解释
方法:
该题解采用了滑动窗口和哈希表的方法。首先,使用哈希表`ds`来记录窗口内元素的出现次数,以及变量`s`来记录窗口内元素的和。窗口的初始位置是数组的前`k`个元素。然后,遍历数组,每次向右滑动窗口一位,更新窗口内的元素和以及哈希表的内容。如果在滑动后的窗口中,哈希表的大小(即窗口内不同元素的数量)大于等于`m`,那么就尝试更新最大和`res`。最终返回得到的最大和`res`,如果没有符合条件的子数组,则返回`0`。
时间复杂度:
O(n)
空间复杂度:
O(k)
代码细节讲解
🦆
在处理滑动窗口中的元素时,哈希表的更新策略是什么,特别是在处理元素频率为0时,为什么要从哈希表中删除该元素?
▷🦆
在更新窗口和时,为什么只考虑移除最左侧元素和添加新元素,这种操作是否足以维持窗口长度始终为k?
▷🦆
题解中提到如果没有符合条件的子数组则返回0,该如何判断是否存在符合条件的子数组?
▷🦆
为什么在每次滑动窗口后只有当窗口内不同元素的数量大于等于m时,才尝试更新最大和?
▷