leetcode 窗口滑动部分题总结

做了leetcode窗口滑动的部分题目

3. 无重复字符的最长子串
76. 最小覆盖子串
209. 长度最小的子数组
438. 找到字符串中所有字母异位词
567. 字符串的排列
1004. 最大连续1的个数 III

有关子串、子数组问题都可以考虑滑动窗口

我自己写的窗口滑动的题的大致模板是这样的:

							for i ,c in enumerate(s):
							 		if 不满足条件:
							 				进行下一个循环
							 				看是否需要更新什么值
							 		else:
							 			收缩窗口(增加左边界)
							 			更新结果

所以需要做的2件事情为:

  • 怎样判断是否满足条件
  • 什么时候停止收缩左边界

需要的变量为:

  • res: 记录结果
  • l: 记录左边界
  • 辅助判断是否满足条件的变量,很可能是集合、字典或者栈

下面以这个模板依次讲解每个题
3. 无重复字符的最长子串
在这里插入图片描述
分析:

					for i ,c in enumerate(s):
						 		if 不满足条件:
						 				进行下一个循环
						 				看是否需要更新什么值
						 		else:
						 			收缩窗口(增加左边界)
						 			更新结果

结果是不包含重复字符的子串,就用集合记录窗口中的字符
判断条件:

						for i ,c in enumerate(s):
							 		if c不在集合中:
							 				将c加入到集合中
							 		else:
							 				更新结果
							 			    收缩左边界的值,要想把集合中包括c,左边界必须在上一个c的位置+1,因为有可能 l>c的位置+1
							 			    所以。。。
							 			

代码如下:

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        hashmap={}  #key为字符,value为位置
        res=0
        l=0
        for index,c in enumerate(s):
            if c not in hashmap:
                hashmap[c]=index
            else:
                l=max(1+hashmap[c],l)  #这个地方更新左边的时候,有可能l的值比hashmap[c]+1要大
                hashmap[c]=index
            res=max(res,index-l+1)
        return res

76. 最小覆盖子串
在这里插入图片描述

滑动窗口外面的时间复杂度为O(n),所以外层循环里面不能出现循环,但是我用了循环。。。。菜鸡的卑微

用两个哈希表req、count分别记录满足条件的子串每个字符应该出现的个数和每个字符已经出现的个数,

						for _ in req:
							if 对于每个 _ ,都有count[_] >req[_],满足条件,开始收缩左边界
							否则,进行下一个循环

代码:

class Solution(object):
    def minWindow(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: str
        """
        res=''
        l=0

        req=defaultdict(int)
        for i in t:
            req[i]+=1

        count=defaultdict(int)
        for r,c in enumerate(s):
            count[c]+=1
            flag=0  #flag为1时,不满足条件,进行下一个字符,怎样判断不满足条件,
            for _ in req:
                if req[_]>count[_]:
                    flag=1
                    break
            if flag:
                continue
            if not flag:  #满足条件,收缩左边界
                while count[s[l]]>req[s[l]]:
                    count[s[l]]-=1
                    l+=1
            if  not res:
                res=s[l:r+1]
            else:
                res=res if len(res)<r-l+1 else s[l:r+1]
        return res

上面的每个题都是如此,先去吃饭,有时间更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值