同向指针滑窗 Same Direction Pointer/Sliding Window
思路
同向双指针可以维护长度可变的滑动窗口。
关键是找到单调性:移动边界后,能够一次判断一批子数组或元素是否满足条件。
同向双指针是一种可变的滑动窗口,固定的叫做滑动窗口。最重要的就是要发现单调性,发现可以通过一次比较来发现多个相同条件的子数组/元素
滑动窗口模板速查
# https://leetcode.cn/problems/max-consecutive-ones-iii/solutions/609055/fen-xiang-hua-dong-chuang-kou-mo-ban-mia-f76z/
def findSubArray(nums):
n = len(nums)
left, right = 0, 0
sums = 0 # 用于统计 子数组/子区间 是否有效,根据题目可能会改成求和/计数
res = 0 # 保存最大的满足题目要 求的 子数组/子串 长度
while right < n:
sums += nums[right] # 增加当前右边指针的数字/字符的求和/计数
while 区间[left, right]不符合题意: # 此时需要一直移动左指针,直至找到一个符合题意的区间
sums -= nums[left] # 移动左指针前需要从 counter 中减少left位置字符的求和/计数
left += 1 # 移动左指针,注意不能跟上面一行代码写反
# 到 while 结束时,我们找到了一个符合题意要求的 子数组/子串
res = max(res, right - left + 1) # 需要更新结果
right += 1 # 移动右指针,去探索新的区间
return res
209. 长度最小的子数组 / Minimum Size Subarray Sum
简要题意: 在正整数数组 nums 中,找和至少为 target 的最短非空连续子数组,返回长度;不存在时返回 0。
子数组(subarray)是数组中一段连续且非空的元素序列。
func minSubArrayLen(target int, nums []int) int {
left := 0
minLen := len(nums) + 1 // This is to mock the infinite
sum := 0
for right := 0 ; right < len(nums) ; right++ {
sum += nums[right]
for sum >= target {
if minLen > right - left + 1 {
minLen = right - left + 1
}
sum -= nums[left]
left++
}
}
if minLen == len(nums) + 1 { // Skip the non-updated case
return 0
} else {
return minLen
}
}