給定兩個字符串 s 和 p,找到 s 中所有 p 的 異位詞的子串,返回這些子串的起始索引。不考慮答案輸出的順序。
示例 1:
輸入: s = “cbaebabacd”, p = “abc”
輸出: [0,6]
解釋: 起始索引等于 0 的子串是 “cba”, 它是"abc" 的異位詞。 起始索引等于 6 的子串是 “bac”, 它是 “abc” 的異位詞。
示例 2:
輸入: s = “abab”, p = “ab”
輸出: [0,1,2]
解釋: 起始索引等于 0 的子串是 “ab”, 它是 “ab”
的異位詞。 起始索引等于 1 的子串是 “ba”, 它是 “ab” 的異位詞。 起始索引等于 2 的子串是 “ab”, 它是 “ab”
的異位詞。
提示:
1 <= s.length, p.length <= 3 * 104 s 和 p 僅包含小寫字母
我最開始用的排序來確定兩個字符串是否相等,但在一些長的字符串上就沒有那么好用。所以使用這個:collections.Counter這個操作可以返回一個字典,存儲對象的出現頻率。比如 p = “aabb”,那么 Counter(p)的結果是一個字典:Counter({‘a’: 2, ‘b’: 2})。
大體思路如下:使用一個先加后減的原則,首先初始化滑動窗口(從0到n-1)的字符頻率為一個字典,然后從n-1開始遍歷,先添加當前字符到字典中,如果該字典與p的頻率字典相等,可判定為是異位詞的子串,將1-n+1添加到結果列表中(目前的i是指向滑動窗口結尾的,需要減掉滑動窗口的長度),不管是否如此,都需要移除左邊的字符,然后在下一次循環的時候加入右邊新的字符。
另外:如果頻率等于0,要注意移除key,不然字典會對應不上。
后來知道,這個思想叫滑動窗口。
class Solution(object):def findAnagrams(self, s, p):""":type s: str:type p: str:rtype: List[int]"""from collections import Counterp_count = Counter(p)n = len(p)ans = []window_count = Counter(s[:n - 1])for i in range(n - 1, len(s)):window_count[s[i]] += 1if window_count == p_count:ans.append(i - n + 1)window_count[s[i - n + 1]] -= 1if window_count[s[i - n + 1]] == 0:del window_count[s[i - n + 1]]return ans