leetcode周赛第二题6230. 长度为 K 子数组中的最大和

题目: 给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和:

子数组的长度是 k,且 子数组中的所有元素 各不相同 。 返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件,返回 0 。

子数组 是数组中一段连续非空的元素序列。

示例 1:

输入:nums = [1,5,4,2,9,9,9], k = 3 输出:15 解释:nums 中长度为 3 的子数组是:

    [1,5,4] 满足全部条件,和为 10 。 [5,4,2] 满足全部条件,和为 11 。 [4,2,9] 满足全部条件,和为 15 。 [2,9,9] 不满足全部条件,因为元素 9 出现重复。 [9,9,9] 不满足全部条件,因为元素 9 出现重复。 因为 15 是满足全部条件的所有子数组中的最大子数组和,所以返回 15 。 示例 2:

输入:nums = [4,4,4], k = 3 输出:0 解释:nums 中长度为 3 的子数组是:

    [4,4,4] 不满足全部条件,因为元素 4 出现重复。 因为不存在满足全部条件的子数组,所以返回 0 。

提示: 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;
    }
};
经验分享 程序员 微信小程序 职场和发展