Skip to content

Latest commit

 

History

History
90 lines (65 loc) · 2.59 KB

438-find-all-anagrams-in-a-string.md

File metadata and controls

90 lines (65 loc) · 2.59 KB

给定一个字符串 和一个非空字符串 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" 的字母异位词。

Solutions

1. 使用 Hash

用 map m 存储 p 中元素个数。再用快慢指针(滑动窗口)对 m 做操作。当某个字母个数为 0 时。将它从 m 删除。如果某一次滑动 len(m) == 0。此时 l 就是满足条件的值之一。一直滑动到 s 末尾。

from collections import defaultdict

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        if len(s) < len(p):
            return []
        
        m = defaultdict(lambda: 0)
        for i in p:
            m[i] += 1
        
        def add(v):
            m[v] += 1
            if m[v] == 0:
                del m[v]
        
        def rm(v):
            m[v] -= 1
            if m[v] == 0:
                del m[v]
        
        results = []
        l, r = 0, 0
        while r < len(p):
            rm(s[r])
            r += 1

        while r < len(s):
            if len(m) == 0:
                results.append(l)
            rm(s[r])
            r += 1
            add(s[l])
            l += 1

        if len(m) == 0:
            results.append(l)

        return results