438. Find All Anagrams in a String 找到字符串中所有字母異位詞
阿新 • • 發佈:2019-05-02
app while pan temp 左移 pen 語句 port code
1. 原始題目
給定一個字符串 s 和一個非空字符串 p,找到 s 中所有是 p 的字母異位詞的子串,返回這些子串的起始索引。
字符串只包含小寫英文字母,並且字符串 s 和 p 的長度都不超過 20100。
說明:
- 字母異位詞指字母相同,但排列不同的字符串。
- 不考慮答案輸出的順序。
示例 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" 的字母異位詞。
2. 思路
雙指針滑動窗口。[i,j]為左閉又閉區間表示當前的子串。如果下一個位置,即j+1位置的字符在目標串中,且其當前出現次數小於目標串中出現的次數則加入當前串。否則前指針一直向右走。如果j+1位置的字符壓根不在目標串中,則將j和i同時更新。
3. 解法
1 from collections import Counter,defaultdict
2 class Solution:
3 def findAnagrams(self, s: str, p: str):
4 c = Counter(p) # 目標串的counter,記錄每個元素出現的次數
5 temp = defaultdict(int) # 當前的子串字典
6 i,j=0,-1 # 【i,j】左閉又閉區間表示當前的子串
7 res = [] # 記錄結果
8 while(i<len(s) and (j+1)<len(s)):
9
10 if s[j+1] in c: # 如果下一個元素在目標串中
11 if temp[s[j+1]]<c[s[j+1]]: # 如果計數小於目標串的計數
12 temp[s[j+1]] +=1 # 更新子串字典
13 j+=1
14 else:
15 temp[s[i]]-=1 # 否則更新子串字典,左移指針
16 i+=1
17 else: # 如果當前字符壓根兒沒有出現在目標串中,更新i,j,當前子串
18 j=j+1
19 i=j+1
21 temp = defaultdict(int)
22 if temp==c: # 這條語句一定要放左最後!當前面判斷完之後,後面要判斷當前子串和目標一樣不
23 res.append(i)
24 temp[s[i]]-=1
25 i+=1
26
27 return res
438. Find All Anagrams in a String 找到字符串中所有字母異位詞