题目:
给你一个整数数组 nums 和一个整数 k 。请你从 nums 中满足下述条件的全部子数组中找出最大子数组和:
- 子数组的长度是
k,且 - 子数组中的所有元素 各不相同 。
返回满足题面要求的最大子数组和。如果不存在子数组满足这些条件,返回 0 。
子数组 是数组中一段连续非空的元素序列。
示例 :
输入: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 。
思路 数组中连续子串的最大最小值之类的题目,基本是使用滑动窗口的形式
解题方法
1.定义的变量有:左右指针,最大值,当前窗口的和,当前窗口map
-
左右指针都从0开始,每次移动一步右指针,并将值加入到当前窗口的和(+)
-
判断当前map中是否存在重复的元素,如果重复 则将左指针指向到右指针,右指针继续向前移动(本题真是可行的), 否则判断当前窗口的数量是否等于k, 如果等于k则将当前窗口的和与结果返回值比较,去两者中更大的作为返回值,同时也将窗口左边向前移动一位
function maximumSubarraySum(nums, k) {
if ([...new Set(nums)].length < k) return 0
let result = 0
let tempResult = 0
let l = 0,
r = 0,
length = nums.length
let map = new Map()
while (r < length) {
map.set(nums[r], map.get(nums[r]) + 1 || 1)
tempResult += nums[r]
if (map.get(nums[r]) > 1) {
map.clear()
l = r
tempResult = nums[l]
map.set(nums[l], 1)
} else if (map.size >= k) {
map.delete(nums[l])
result = Math.max(result, tempResult)
tempResult -= nums[l]
l++
}
r++
}
return result
}
ps: 本题是本周的周赛题,没写出来,超时了,所以来总结一下,如果是按照我的计划是现在不考虑中等题的