滑動窗口算法

參考文章:leetcode438題解答

0x00:前言

leetcode上有好幾道個子字符串有關的題目,兩天前看到一題要求找到字符串中所有字母異位詞,題目大致意思是有s和p兩個字符串,找出s中和p字母相同但順序可以不相同的子字符串,並返回這些子串的起始索引。

例子:
輸入:
s: "cbaebabacd" p: "abc"
輸出:
[0, 6]
解釋:
起始索引等於 0 的子串是 "cba", 它是 "abc" 的字母異位詞。
起始索引等於 6 的子串是 "bac", 它是 "abc" 的字母異位詞。
題目鏈接:https://leetcode-cn.com/probl...

0x01:算法思路

想象一塊在窗口上滑動的玻璃窗,它的“左”邊和“右”邊都是可以移動的,也就是這個玻璃窗的位置可以移動,寬度也可以變化。這麼一說好像更像窗簾……

思路如下:

  1. 建立雙指針,初始化left與right兩個指針,以[left, right]這個閉區間做爲窗口
  2. 首先拉動這個窗口的右邊,窗口不斷擴大,直到窗口中內容符合要求
  3. 現在移動窗口的左邊,直到窗口中內容不符合要求
  4. 重複2、3步驟,直到窗口右邊達到邊界

使用這種方式,可以方便的解決子字符串相關問題。

0x02:具體解決

  • 首先在代碼中,雙指針rightleft不能少,同時還需要一個值來記錄匹配情況
  • 返回值需要一個列表,來記錄匹配的子字符串首位索引
  • 使用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

掃描二維碼關注公衆號查看更多文章:
圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章