滑动窗口问题

目前的理解,双指针,滑动窗口就是左右指针之间的窗口,指针可以左右移动。然后用一些条件决定是哪边的指针移动,是向左还是向右移动,移动多少。

力扣209 长度最小的子数组

题目描述:

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # 滑动窗口的思想,双指针

        n = len(nums)
        ans = n + 1
        s = 0
        left = 0
        for right, x in enumerate(nums): # x = nums[right]
            # 每次将右端点包括进去,然后左端点不断右移直到不再满足需求
            s += x
            # while s - nums[left] >= target:
            #     s -= nums[left]
            #     left += 1
            # if s >= target:
            #     ans = min(ans, right - left + 1)
            # 另一种写法
            while s >= target:
                ans = min(ans, right - left + 1)
                s -= nums[left]
                left += 1
        return ans if ans <= n else 0

力扣3 无重复字符的最长子串

题目描述:

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # hashmap key:char value:int 
        ans = 0
        cnt = Counter() # 哈希表记录的是字符出现的次数
        left = 0
        for right,x in enumerate(s):
            # 每次都将右边的值包括进去,更新左端点
            cnt[x] += 1
            while cnt[x] > 1:
                cnt[s[left]] -= 1
                left += 1
            ans = max(ans, right - left + 1)
        return ans

力扣713 乘积小于K的子数组

题目描述:

给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。

输入:nums = [10,5,2,6], k = 100

输出:8

解释:8 个乘积小于 100 的子数组分别为:[10]、[5]、[2]、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。 需要注意的是 [10,5,2] 并不是乘积小于 100 的子数组。

class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        # 同209
        if k <= 1:
            return 0
        n = len(nums)
        prod = 1
        left = 0
        ans = 0
        for right, x in enumerate(nums):
            prod *= x
            while prod >= k:
                prod /= nums[left]
                left += 1
            ans += right - left + 1
        return ans

滑动窗口是一种常用的算法技巧,在并行操作中也有广泛应用。从提供的引用来看,虽未直接提及并行操作下滑动窗口问题的内容,但可从常规滑动窗口原理和解决思路进行一定推导。 ### 原理 在常规场景下,滑动窗口原理在TCP中有体现,TCP窗口机制有固定窗口大小和滑动窗口两种。发送方和接收方分别保持一个窗口,发送方只有落在发送窗口内的数据帧才允许被发送,接收方只有落在接收窗口内的数据才会被接收,通过改变发送窗口和接收窗口的大小实现流量控制[^5]。在并行操作中,其原理可类比为在多个数据序列或任务流上同时维护多个窗口,每个窗口独立或协同地在数据上滑动,以满足特定条件。例如在多个线程或进程中同时处理不同的数据块,每个线程或进程可以维护一个滑动窗口来处理其负责的数据。 ### 解决方法 - **模板化方法**:对于普通滑动窗口问题有通用模板,定义滑动窗口的左右下标,通过循环判断条件来移动左右指针,同时在合适的时候做除指针移动之外的其他操作。在并行操作中,可以为每个并行任务分配一个这样的窗口,每个窗口独立执行该模板逻辑。如在多个线程中,每个线程负责一个数据子集,使用如下类似代码模板: ```java class Solution { public int minSubArrayLen(int s, int[] a) { int l = 0, r = -1; // 定义滑动窗口两下标 while (l < a.length) { if (r + 1 < a.length && 另一个条件) { // r+1要小于输入长度 // 只做l++ 或者 ++r相关操作 } else { // 只做l++ 或者 ++r相关操作 } // 做除了l++ 或者 r++之外的其他操作 } } } ``` - **逆向思维与条件判断**:在一些问题中可以采用逆向思维,将问题转换为更易处理的形式。如将找到满足特定和的最小子数组问题转换为找到最大连续子数组使其和为特定值的问题。在并行操作中,每个并行任务可以独立判断窗口内的条件是否满足要求,若不满足则移动窗口指针。同时还需要注意特殊情况的判断,避免出现死循环等问题[^2]。 - **窗口指针移动规则**:左指针的功能是用来缩小窗口的,当窗口内的条件已满足题目条件或多于题目条件时,缩小窗口,即左指针右移直到窗口条件不满足为止,记录当前窗口大小并更新满足条件的最小窗口记录,之后再次扩展右指针使窗口满足条件。在并行操作中,每个并行任务的窗口都遵循此规则移动指针[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值