题目:
给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和:
子数组的长度是 k,且
子数组中的所有元素 各不相同 。
返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件,返回 0 。
子数组 是数组中一段连续非空的元素序列。
示例 1:
输入:nums = [1,5,4,2,9,9,9], k = 3
输出:15
解释:nums 中长度为 3 的子数组是:
输入:nums = [4,4,4], k = 3
输出:0
解释:nums 中长度为 3 的子数组是:
提示:
1 <= k <= nums.length <= 105
1 <= nums[i] <= 105
自我反思:
当时做的时候卡壳了,不知道怎么应对重复这个限制,想着用set,试了一下又卡住了23333,之后看了一下大佬题解,才知道用hash表
好了,言归正传,思路就是,滑动窗口+hashmap,
开始先把前k个数存入hash表并计数,同时对这k个数求和,
然后每滑动一下,把新元素加到hashmap中,当前窗口的最左端的元素,删掉,每次一增一删的同时,判断一下当前的元素个数是不是k个,如果是k个说明满足题目要求,把它和结果求一下最大值,以此类推。。
class Solution {
public:
long long maximumSubarraySum(vector<int>& nums, int k) {
unordered_map<int, int> mp;
long long sum = 0;
long long ans = 0;
int n = nums.size();
for(int i = 0;i < k;i ++) mp[nums[i]] ++, sum += nums[i];
if(mp.size() == k) ans = max(ans, sum);
int l = 0;
for(int i = k;i < n;i ++){
mp[nums[i]] ++, sum += nums[i];
auto t = mp.find(nums[l]); // 这里t是一个整体,key value
if(t->second == 1) mp.erase(t);
else t->second --;
sum -= nums[l++];
if(mp.size() == k) ans = max(ans, sum);
}
return ans;
}
};