几乎唯一子数组的最大和
约 621 字大约 2 分钟
2025-01-05
几乎唯一子数组的最大和
给你一个整数数组nums
和两个正整数m
和k
。
请你返回nums
中长度为k
的 几乎唯一 子数组的最大和如果不存在几乎唯一子数组,请你返回0
。
如果nums
的一个子数组有至少m
个互不相同的元素,我们称它是几乎唯一子数组。
子数组指的是一个数组中一段连续非空的元素序列。
示例 1:
输入:nums = [2,6,7,3,1,7], m = 3, k = 4
输出:18
解释:总共有 3 个长度为 4 的子数组。分别为 [2, 6, 7, 3] ,[6, 7, 3, 1] 和 [7, 3, 1, 7] 。 这些子数组中,[2, 6, 7, 3] 和 [3, 1, 7] 有 3 个互不相同的元素。其中,[2, 6, 7, 3] 的和是 18 ,是最大的和。
示例 2:
输入:nums = [5,9,9,2,4,5,4], m = 1, k = 3
输出:23
解释:总共有 5 个长度为 3 的子数组。分别为 [5, 9, 9] ,[9, 9, 2] ,[9, 2, 4] ,[2, 4, 5] 和 [4, 5, 4] 。 这些子数组中,只有 [5, 9, 9] 存在 1 个互不相同的元素,所以我们返回 23 。
示例 3:
输入:nums = [1,2,1,2,1,2,1], m = 3, k = 3
输出:0
解释:输入数组中不存在长度为 k = 3 的子数组含有至少 m = 3 个互不相同元素的子数组。所以不存在几乎唯一子数组,最大和为 0 。
这题也是一眼滑动窗口,但是需要注意的是,需要记录窗口中互不相同的元素数量,然后每次移动窗口时,需要更新窗口中互不相同的元素数量。
判断几乎唯一这个条件可以使用 map 来实现。key 为元素,value 为元素出现的次数。 map 的大小即为不重复元素的个数。
class Solution {
public:
long long maxSum(vector<int>& nums, int m, int k) {
long long res =0;
long long s =0;
int n = nums.size();
unordered_map<int,int> hsmap;
if(n < k ) return res;
//先添加k-1个数
for(int i =0;i<k-1;++i){
s += nums[i];
hsmap[nums[i]]++;
}
for(int i = k-1;i<n;++i){
s += nums[i]; // 再添加一个数就是 k 个数了
hsmap[nums[i]]++;
if (hsmap.size() >= m) {
res = max(res, s);
}
int out = nums[i - k + 1];
s -= out; // 下一个子数组不包含 out,移出窗口
if (--hsmap[out] == 0) {
hsmap.erase(out);
}
}
return res;
}
};
更新日志
d33e4
-寒假更新每日一题day2于