问题:这类问题非常常见,是双指针中的一种——同向双指针问题。问题求解思路是,定义left与right索引,right从0开始累加/统计/乘积等操作。这样做最终导致结果超出条件,因此需要left进行兜底,使用循环左移left直到满足条件为止。统计结果。
求最大/最长/最小:
在2958. 最多 K 个重复元素的最长子数组 - 力扣(LeetCode)中,right遍历nums,使用map存储元素频率,再使用for循环左移left,保证结果满足条件,统计结果即可。
func maxSubarrayLength(nums []int, k int) int {
mp:=make(map[int]int)
res:=math.MinInt32
for left,right:=0,0;right<len(nums);right++{
mp[nums[right]]++
for mp[nums[right]]>k{
mp[nums[left]]--
left++
}
res=max(res,right-left+1)
fmt.Println(res)
}
return res
}
func max(a,b int)int{
if a>b {
return a
}
return b
}
求个数:
在2537. 统计好子数组的数目 - 力扣(LeetCode)中,统计子数组个数,这种问题,必须要注意,需要固定一个端点,求遍历过的元素中,满足条件的子数组个数。否则容易漏算、超算。
本题,固定/枚举右端点,然后逐渐右移左端点,看看最少能移动到那个位置,循环结束,只需要统计left左侧位置的元素个数+1即可。
func countGood(nums []int, k int) (ans int64) {
cnt := map[int]int{}
left, pairs := 0, 0
for _, x := range nums {
pairs += cnt[x]
cnt[x]++
for pairs-cnt[nums[left]]+1 >= k {
cnt[nums[left]]--
pairs -= cnt[nums[left]]
left++
}
if pairs >= k {
ans += int64(left + 1)
}
}
return
}
总而言之,滑动窗口一般求解:for循环遍历right,然后累加/统计nums[right],在通过内层for循环左移left,直到满足条件为止,统计结果即可。
对于更高阶应用,需要结合其他知识,比如栈与队列,后续会逐渐涉及。