2841.几乎唯一子数组的最大和


给你一个整数数组 nums 和两个正整数 mk

请你返回 nums 中长度为 k几乎唯一 子数组的 最大和 ,如果不存在几乎唯一子数组,请你返回 0

如果 nums 的一个子数组有至少 m 个互不相同的元素,我们称它是 几乎唯一 子数组。

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

示例 1:

输入:nums = [2,6,7,3,1,7], m = 3, k = 4
输出:18
解释:总共有 3 个长度为 k = 4 的几乎唯一子数组。分别为 [2, 6, 7, 3] ,[6, 7, 3, 1] 和 [7, 3, 1, 7] 。这些子数组中,和最大的是 [2, 6, 7, 3] ,和为 18 。

示例 2:

输入:nums = [5,9,9,2,4,5,4], m = 1, k = 3
输出:23
解释:总共有 5 个长度为 k = 3 的几乎唯一子数组。分别为 [5, 9, 9] ,[9, 9, 2] ,[9, 2, 4] ,[2, 4, 5] 和 [4, 5, 4] 。这些子数组中,和最大的是 [5, 9, 9] ,和为 23 。

示例 3:

输入:nums = [1,2,1,2,1,2,1], m = 3, k = 3
输出:0
解释:输入数组中不存在长度为 k = 3 的子数组含有至少  m = 3 个互不相同元素的子数组。所以不存在几乎唯一子数组,最大和为 0 。

提示:

  • 1 <= nums.length <= 2 * 10^4
  • 1 <= m <= k <= nums.length
  • 1 <= nums[i] <= 10^9
class Solution {
    public long maxSum(List<Integer> nums, int m, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        int size = nums.size();
        if(size < k){
            return 0l;
        }
        long maxSum = 0;
        for(int i = 0; i < k; i++){
            map.put(nums.get(i),map.getOrDefault(nums.get(i),0)+1);
            maxSum += nums.get(i);
        }

        long maxResult = 0;

        //如果key的值大于m则认为存在唯一子数组
        if(map.keySet().size() >= m){
            maxResult = maxSum;
        }

        for(int i = k; i < size; i++){
            //首先删除 i-k的值
            //加上 i的值
            //得到sum值.
            maxSum = maxSum - nums.get(i-k) + nums.get(i);

            // map中去除 i-k的值
            if(map.get(nums.get(i-k)) == 1){
                map.remove(nums.get(i-k));
            } else {
                map.put(nums.get(i-k),map.get(nums.get(i-k))-1);
            }

            //map中增加 i 的值
            map.put(nums.get(i),map.getOrDefault(nums.get(i),0)+1);

            //判断map的keyset是否满足诉求,如果满足,则比较大小.
            if(map.keySet().size() >= m){
                maxResult = Math.max(maxSum,maxResult);
            }
        }
        return maxResult;
    }
}

文章作者: 冯廷鑫
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 冯廷鑫 !
  目录