您的位置:首页 > 其它

438. Find All Anagrams in a String

2016-11-17 11:31 465 查看
Given a string s and a non-empty string p, find all the start indices of p’s anagrams in s.

Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

The order of output does not matter.

Example 1:

**Input:**
s: "cbaebabacd" p: "abc"

**Output:**
[0, 6]

**Explanation:**
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".


Example 2:

**Input:**
s: "abab" p: "ab"

**Output:**
[0, 1, 2]

**Explanation:**
The substring with start index = 0 is "ab", which is an anagram of "ab".
The substring with start index = 1 is "ba", which is an anagram of "ab".
The substring with start index = 2 is "ab", which is an anagram of "ab".


开始的代码,会超时,负载度是 (n-k)k量级的。

复杂的主要是原因是14行的for循环里,每次都重新来定义一个新的字典。

class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
ns=len(s)
np=len(p)
ans=[]
d={}
for i in p:
d[i]=d.get(i,0)+1
for i in range(ns-np+1):
if self.constrast(s[i:i+np],d):
ans.append(i)
return ans

def constrast(self,s,d):
d1={}
for i in s:
d1[i]=d1.get(i,0)+1
return d1==d


考虑,用不新的来定义字典来重做。

- 因为只有小写的字母,最多26个,考虑用长度为26的两个list代替上文的字典

- 每一次移动,s所对应的list做出相应的更新,这样就避免了最开始代码每次的重新构造。

96.24%

class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
ns = len(s)
np = len(p)
ans = []
if not ns or np>ns:return ans
lists=[0]*26
listp=[0]*26
for i in range(np):
listp[ord(p[i])-97] += 1
lists[ord(s[i])-97] += 1
for j in range(ns-np+1):
if j:
lists[ord(s[j-1]) - 97]-=1
lists[ord(s[j-1+np]) - 97] += 1
if listp==lists:
ans.append(j)
return ans


字典版本:81.31%

class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
ns = len(s)
np = len(p)
ans = []
if not ns or np>ns:return ans
lists={}
listp={}
for i in range(np):
listp[p[i]]=listp.get(p[i],0)+ 1
lists[s[i]] =lists.get(s[i],0)+ 1
for j in range(ns-np+1):
if j:
if lists[s[j-1]]==1:
lists.pop(s[j-1])
else:
lists[s[j - 1]]-=1
lists[s[j-1+np]] =lists.get(s[j-1+np],0)+ 1
if listp==lists:
ans.append(j)
return ans
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode