📜  门| GATE-CS-2005 |第 85 题(1)

📅  最后修改于: 2023-12-03 15:42:15.950000             🧑  作者: Mango

题目描述

给定两个字符串S1和S2,写一个函数来判断S2是否包含S1的所有字符的排列。如果是,则返回True,否则返回False。

换句话说,一个字符串X是另一个字符串Y的一个排列,当且仅当X具有与Y相同的字符,每个字符的出现次数也相同(或者说等价于两个字符串是由重新排列的相同的字符组成的,但它们的顺序不同)。

函数签名
def check_inclusion(self, s1: str, s2: str) -> bool:
    pass
输入
  • s1:一个字符串,1≤len(s1)≤10^4
  • s2:另一个字符串,1≤len(s2)≤10^4
输出
  • 返回一个布尔型值,表示s2是否包含s1的所有字符的排列。
示例

输入:

s1 = 'ab'
s2 = 'eidbaooo'

输出:

True

解释:

  • s2 包含 baab的一个排列。
题解

本题解采用滑动窗口的思想。具体实现步骤如下:

  1. 统计 s1 中每个字符出现的次数,保存在一个字典 count_dict
  2. 定义长度为 len(s1) 的滑动窗口,依次遍历 s2 的每个字符
    • 如果该字符不在 s1 中,则滑动窗口左端点右移
    • 如果该字符在 s1 中,统计该字符在滑动窗口中出现的次数,保存在一个字典 window_dict
    • 如果滑动窗口中的某个字符出现的次数大于 count_dict 中的该字符出现的次数,则滑动窗口左端点右移
    • 如果滑动窗口中的字符数等于 s1 的字符数,则说明 s2 中包含 s1 的所有字符的排列,返回 True
  3. 如果遍历完 s2 后仍未返回 True,则返回 False

详见下面的 Python 代码:

class Solution:
    def check_inclusion(self, s1: str, s2: str) -> bool:
        count_dict = {}
        for c in s1:
            count_dict[c] = count_dict.get(c, 0) + 1
        window_dict = {}
        left = right = 0
        while right < len(s2):
            c = s2[right]
            right += 1
            if c not in count_dict:
                left = right
                window_dict.clear()
            else:
                window_dict[c] = window_dict.get(c, 0) + 1
                while window_dict[c] > count_dict[c]:
                    d = s2[left]
                    left += 1
                    window_dict[d] -= 1
                if right - left == len(s1):
                    return True
        return False

时间复杂度 $O(len(s1) + len(s2))$,空间复杂度 $O(len(s1))$。

参考资料