题目
给你一个整数数组 nums
和两个正整数 m
和 k
。
请你返回 nums
中长度为 k
的 几乎唯一 子数组的 最大和 ,如果不存在几乎唯一子数组,请你返回 0
。
如果 nums
的一个子数组有至少 m
个互不相同的元素,我们称它是 几乎唯一 子数组。
子数组指的是一个数组中一段连续 非空 的元素序列。
示例 1:
1 2 3
| 输入: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:
1 2 3
| 输入: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:
1 2 3
| 输入:nums = [1,2,1,2,1,2,1], m = 3, k = 3 输出:0 解释:输入数组中不存在长度为 k = 3 的子数组含有至少 m = 3 个互不相同元素的子数组。所以不存在几乎唯一子数组,最大和为 0 。
|
提示:
1 <= nums.length <= 2 * 104
1 <= m <= k <= nums.length
1 <= nums[i] <= 109
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Solution { public long maxSum(List<Integer> nums, int m, int k) { HashMap<Integer ,Integer> map = new HashMap<>(); int n=nums.size(); long max=0; long sum=0; for(int i=0;i<n;i++){ sum+=nums.get(i); if(map.containsKey(nums.get(i))){ map.put(nums.get(i),map.get(nums.get(i))+1); }else{ map.put(nums.get(i),1); } if(i<k-1){ continue; } if(sum>max&&map.size()>=m){ max=sum; } sum-=nums.get(i-(k-1)); if(map.get(nums.get(i-(k-1)))==1){ map.remove(nums.get(i-(k-1))); }else{ map.put(nums.get(i-(k-1)),map.get(nums.get(i-(k-1)))-1); } } return max; } }
|
知识点
思路:求子数组的 最大和是常规定长滑动窗口问题,这题对我来说难点在于如何判断唯一,我想到使用哈希表,它能保证键唯一。哈希表的键为该位置i
的原数组的值,哈希表的值为该值在一个滑动窗口中出现的次数。