[python 刷题] 567 Permutation in String

[python 刷题] 567 Permutation in String

题目:

Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise.

In other words, return true if one of s1’s permutations is the substring of s2.

这个问题问的是 s2 中有没有 s1 的排列组合。如果说 s1abc 的话,s2 可以包含 abc, bca, bac, cba, cab

这道题的思路和 [python 刷题] 424 Longest Repeating Character Replacement 挺像的,依旧使用 dict+sliding window 实现,不过与其对比使用传统的 dict,这里会用 Counter,方便解决默认值的问题。

以 lc 提供的案例来说:Input: s1 = "ab", s2 = "eidbaooo"

遍历第一个字符 e 时,因为 s1 中不包含这个字符,所以重制 s2 的 Counter,并且继续往下走循环,同时将左侧指针移到下一个字符:

[python 刷题] 567 Permutation in String_第1张图片

同样的操作一直到 b,这个时候因为 s1 中包含 b,所以左侧的指针停留在这里:

[python 刷题] 567 Permutation in String_第2张图片

当右指针移到字符 a 时,出现 s1 == s2 的情况,这时候就可以直接返回 True 了:

[python 刷题] 567 Permutation in String_第3张图片

需要注意这里有一个特殊情况,就是 Input: s1 = "ab", s2 = "aaaabbbbb" 的情况。这种情况下 s2 是包含 s1 ,不过如果只是按照上面的逻辑,就会出现:

[python 刷题] 567 Permutation in String_第4张图片

这样的情况

因此如果 s2 中对应的数量大于左侧指针时,需要不断地将左侧指针向右移。

又因为如果遇到了 s1 中不包含的字符,那么 Counter 就会重置,并且左侧的指针指向 r + 1 r + 1 r+1,因此 [ s 2 [ l ] , . . . , s 2 [ r ] ] [s2[l], ..., s2[r]] [s2[l],...,s2[r]] 中的内容一定是包含在 s1 中的,只是出现的频率可能会不一样而已

代码如下:

class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        c1 = collections.Counter(s1)

        l = 0
        c2 = collections.Counter()
        for r, ch in enumerate(s2):
            if ch not in c1:
                c2 = collections.Counter()
                l = r + 1
                continue

            c2[ch] += 1
            while c2[s2[l]] > c1[s2[l]]:
                c2[s2[l]] -= 1
                l += 1

            if c2 == c1:
                return True

        return False

你可能感兴趣的:(#,leetcode,python,开发语言)