python窗口滑动算法_滑动窗口算法_公子政的宅日常 - SegmentFault 思否

0x00:前言

leetcode上有好几道个子字符串有关的题目,两天前看到一题要求找到字符串中所有字母异位词,题目大致意思是有s和p两个字符串,找出s中和p字母相同但顺序可以不相同的子字符串,并返回这些子串的起始索引。

例子:

输入:

s: "cbaebabacd" p: "abc"

输出:

[0, 6]

解释:

起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。

起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。

题目链接:https://leetcode-cn.com/probl...

0x01:算法思路

想象一块在窗口上滑动的玻璃窗,它的“左”边和“右”边都是可以移动的,也就是这个玻璃窗的位置可以移动,宽度也可以变化。这么一说好像更像窗帘……

思路如下:

建立双指针,初始化left与right两个指针,以[left, right]这个闭区间做为窗口

首先拉动这个窗口的右边,窗口不断扩大,直到窗口中内容符合要求

现在移动窗口的左边,直到窗口中内容不符合要求

重复2、3步骤,直到窗口右边达到边界

使用这种方式,可以方便的解决子字符串相关问题。

0x02:具体解决

首先在代码中,双指针right和left不能少,同时还需要一个值来记录匹配情况

返回值需要一个列表,来记录匹配的子字符串首位索引

使用hash表来记录字符串p中各个字符数量,在Python中使用Count类,它是字典dict的子类,可以使用字典常用的方法

移动right来遍历字符串s,如果right所在的字符存在于t中,将其存入window这个字典中,并将记录其数量的值加一。

window[key] = window.get(key, 0) + 1

# 字典的get方法:dict.get(key, default=None),返回字典中key的值,如果key不存在,就返回默认的default值。

# 这样写保证window[key]值增加1,如果不存在这个键就会创建

当window中记录字符的数量与needs中相等时,表示我们匹配完了一个字符,将match值加一

等到匹配的字符长度合适了,就可以将left的值append到需要返回的列表中去了

while match == len(needs):

if right - left == len(p):

res.append(left)

移动left,直到窗口内容不再符合我们需要的异序字符串,将match值也减一

完整代码如下:

from collections import Counter

class Solution:

def findAnagrams(self, s: str, p: str) -> List[int]:

res = []

right, left, match = 0, 0, 0

needs = Counter(p)

window = {}

while right < len(s):

key1 = s[right]

if key1 in needs:

window[key1] = window.get(key1, 0) + 1

if window[key1] == needs[key1]:

match += 1

right += 1

while match == len(needs):

if right - left == len(p):

res.append(left)

key2 = s[left]

if key2 in needs:

window[key2] = window[key2] - 1

if window[key2] < needs[key2]:

match -= 1

left += 1

return res

扫描二维码关注公众号查看更多文章:

bVbvYcw?w=258&h=258

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值