438. Find All Anagrams in a String

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值