python [LeetCode] 字符串的排列

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

换句话说,第一个字符串的排列之一是第二个字符串的子串。
示例一

输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).

示例二

输入: s1= “ab” s2 = “eidboaoo”
输出: False

注意

输入的字符串只包含小写字母
两个字符串的长度都在 [1, 10,000] 之间

思路一
暴力法。以s1的长度为基准,在s2上滑动比较。
代码
102个用例,耗时296ms,击败17%python3提交记录

class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        length1 = len(s1)
        length2 = len(s2)
        set_s1 = set(s1)    # 将s1字符串转换成集合,这样在后续比较中就可以免去重复字符的比较
        temp = 0            # 记录滑动比较的其实位置
        while temp+length1 <= length2:    #滑动比较的终止条件
            s2_seg = s2[temp:temp+length1]  #在s2上取与s1长度一样的子字符串片段与s1比较
            flag = 1     # 标记,一旦出现字符的个数不同,则flag=0,且退出循环
            for char in set_s1:
                if s1.count(char) != s2_seg.count(char):
                    flag = 0
                    break
            if flag == 1:
                return True
            else:
                temp += 1
        return False

思路二
参考了大神的代码。其实总体思路是相似的,不过建立了字典来存放各字符串不同字母的个数,并滑动比较。
代码
102个用例,耗时76ms,击败93%python3提交记录

class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        l1 = len(s1)
        l2 = len(s2)
        if l2<l1:         #若字符串s2的长度小于s1,则返回false
            return False
        
        s = 'abcdefghijklmnopqrstuvwxyz'
        dict1 = {}
        dict2 = {}
        for char in s:
            dict1[char] = 0          #初始化字典,key为字母,value为字母出现的次数,都初始化为0
            dict2[char] = 0
        for i in range(l1):
            dict1[s1[i]] += 1        # 首先计算前l1长度的不同字母出现次数
            dict2[s2[i]] += 1
        if dict1 == dict2:           # 若两个字典相等,则说明字符串的[0:l1]是字符串l1的不同排列
            return True
        for i in range(l2-l1):       # 开始往后查找,每次移动一个位置
            dict2[s2[i]] -= 1        # 减去滑动比较得前一个字母出现的次数
            dict2[s2[i+l1]] += 1     # 加上滑动后加进来的字母出现的次数
            if dict1 == dict2:       # 若相等,则返回true
                return True
        return False

你可能感兴趣的:(LeetCode)