438. Find All Anagrams in a String

 题目来源:

 自我感觉难度/真实难度:             写题时间时长:

 题意:

 分析:

 自己的代码:

import collections
class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        l=len(s)
        t=len(p)
        
        cs=collections.Counter(s[:t-1])
        cp=collections.Counter(p)
        # cs=collections.defaultdict(int)
        # cp=collections.defaultdict(int)
        # for c in s[:t-1]:
        #     cs[c]+=1
        # for d in p:
        #     cp[d]+=1
        
      
        res=[]
        i=0
        while i+t<=l:
            cs[s[i+t-1]]+=1
            if cs==cp:
                res.append(i)
            cs[s[i]]-=1
            if cs[s[i]]==0:
                del cs[s[i]]
            i+=1
        return res
                

 

这里还验证了一个事情,那就是Counter产生的dict 是会默认int初试值为0

代码效率/结果:

Runtime: 188 ms, faster than 43.60% of Python online submissions for Find All Anagrams in a String.
Memory Usage: 12.7 MB, less than 5.16% of Python online submissions for Find All Anagrams in a String.

 优秀代码:

class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        # method 1, TLE
        # 把字串排序以後在沿路比較...
        # 這一定不行
        #len_p = len(p)
        #sort_p = sorted(p)
        #ans = []
        #s_dict = dict()
        #for idx in range(len(s)-len_p+1):
        #    if sorted(s[idx:idx+len_p]) == sort_p:
        #        ans.append(idx)
        #return ans
        
        # method 2, 68ms, 100%
        # 使用 dict (hashmap)
        # 並且因為 p 是固定長度,
        # 所以另外使用一個變數紀錄長度
        # 來保持新比對的 s 的 dict 也是一樣長度的情況進行比較
        # sliding window
        # 而 p 和 s 的 dict 比對是固定時間 
        # 因為最多就是 26 個字母
        # O(n)
        len_p = len(p)
        p_dict = dict()
        for l in p:
            if l in p_dict:
                p_dict[l] += 1
            else:
                p_dict[l] = 1
        
        ans = []
        chk_len = 0
        s_dict = dict()
        for idx, l in enumerate(s):
            if l not in p_dict:
                chk_len = 0
                s_dict = dict()
            else:
                if chk_len < len_p:
                    chk_len += 1
                else:
                    s_dict[s[idx-chk_len]] -= 1
                    
                if l in s_dict:
                    s_dict[l] += 1
                else:
                    s_dict[l] = 1
                    
                if chk_len == len_p and s_dict == p_dict:
                    ans.append(idx-chk_len+1)
                    
        return ans

68ms,应该是因为没有调用包,其实整体思路还是一样的滑动窗口

代码效率/结果:

 自己优化后的代码:

 反思改进策略:

1.自己的思路还是可以的,就是不敢往下写。

 写简单例子的时候,就要多标注一些基本的下标数字和简单的指示,这样写起来会更流畅,不会被小细节不断打断思路

 

posted @ 2019-05-11 23:48  dgi  阅读(115)  评论(0编辑  收藏  举报