滑动窗口的应用(python实现)

这道题主要是考察滑动窗口的应用,而滑动窗口的程序比较绕,因为边界条件实在是有点复杂,但是套路比较固定,一般在数组中考察,题干一般含有"连续子数组"等字样
参考链接:
https://zhuanlan.zhihu.com/p/61564531

框架

初始化窗口端点L,R,一般L为0,R为1
    初始化最优值
    while R < len(Array):
        while R < len(Array):
            R += 1              #移动右端点
            if R < len(Array):
                更新状态        
            if 状态满足条件:
                可选的更新最优值的位置
                break           #一旦满足条件即跳出
        if R == len(Array):     # 若循环是由于移动到数组末尾结束,则停止整个程序。因为之后已经不再有可能的解
            break
        while L < R:
            更新状态    # 移动左端点,需要更新状态
            L += 1
            if 状态满足条件:
                可选的更新最优值的位置
            else# 一旦窗口所在区间不再满足条件即跳出,去移动右端点
                break
        可选的对于L,R端点的后续处理
    return 最优值

依次解读:
第一层循环保证了右部标记不会超出数组,之后将右部标记移动至刚好满足条件的地方,结束while循环,为什么能够保证第一层循环不会溢出呢,因为只要R不等于数组长度,就可以保证所有的R可能性都已经遍历完了,也就代表着所有对应的左侧标记也已标记完成,即所有情况也已经完成,第二层while循环表示移动左部标记使其不满足条件,然后纪录其状态,之后循环,得到最优位置。

例题:
https://leetcode-cn.com/problems/minimum-size-subarray-sum/

代码:

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left,right,minvalue,sumvalue = 0,-1,float('inf'),0  #初始化,left为
        while(right<len(nums)): #while循环保证
            while(right<len(nums)):
                right += 1 #右边逐渐移动
                if(right<len(nums)):
                    sumvalue+=nums[right]  #一直相加
                if(sumvalue>=target):
                    minvalue = min(minvalue,right-left+1) #在两者之间比较出最小值
                    break
            if(right==len(nums)):
                break
            while(left<right):
                sumvalue-=nums[left]
                left+=1
                if(sumvalue>=target):   #也就是在left+1之后还小于
                    minvalue = min(minvalue,right-left+1)
                else:  #如果还能小就退出
                    break
        if(minvalue==float('inf')):
            return 0
        return minvalue

上面的代码一开始看着有点复杂,但是可以保证许多情况下都适用,

题目

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
这道题其实没什么不同,也就是判断的情况不同了几种,判断最大值仍在right扩大的过程中寻找,因为在left移动时是不会存在最大值的,详细看代码就行

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        left,right, = 0,-1      #将right赋值为-1的好处是第一个循环不会崩掉
        list1 = []  #这里面的数组不会有重复字符
        minvalue = 0
        while(right<len(s)): 
            while(right<len(s)):
                right+=1
                if(right>=len(s)):
                    minvalue = max(minvalue,right-left)  
                    break
                if(s[right] not in list1):  #
                    list1.append(s[right]) #如果不重复就加入数组

                else:       #如果在这里面了就计算最大值
                    minvalue = max(minvalue,right-left) #这里面写right - left的原因是right本身就不算了
                    break
            if(right==len(s)):
                break
            while(left<right):
                if(s[left]!=s[right]):  #如果不等于的话就继续找,并移除数字
                    list1.remove(s[left])
                    left+=1
                else:			#找到了就将left向右移动一格,并退出循环
                    left+=1
                    break    
        return minvalue
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值