剑指 Offer II 014. 字符串中的变位词

剑指 Offer II 014. 字符串中的变位词,第1张

剑指 Offer II 014. 字符串中的变位词 题目

力扣

思路一 滑动窗口

变位词就是字符串中每个字符出现的次数都相同,但是排列顺序不同。统计s1中每个字母出现的次数,用大小为26的vector存储。再维护一个和s1长度相同的滑动窗口,逐渐往右移动,判断该滑动窗口中每个字符出现的次数是否与s1相同,子串中每个字符出现的次数用另一个大小为26的vector存储。

代码一
class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        int m=s1.size(),n=s2.size();
        if(m>n) return false;
        vector hash1(26),hash2(26);
        for(int i=0;i 
class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        m,n=len(s1),len(s2)
        if(m>n):
            return False
        dict1=[0]*26
        dict2=[0]*26
        for i in range(m):
            dict1[ord(s1[i])-ord('a')]+=1
            dict2[ord(s2[i])-ord('a')]+=1
        if(dict1 == dict2):
            return True
        for i in range(m,n):
            dict2[ord(s2[i])-ord('a')]+=1
            dict2[ord(s2[i-m])-ord('a')]-=1
            if(dict1 == dict2):
                return True
        return False
优化思路

每次比较都需要比较两个vector,可以简化成用一个vector存储两个字符串的差异,并用diff变量存储两个字符串出现的字符有差异的个数。

优化代码
class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        m,n=len(s1),len(s2)
        if(m>n):
            return False
        dict=[0]*26
        diff=0
        for i in range(m):
            dict[ord(s1[i])-ord('a')]-=1
            dict[ord(s2[i])-ord('a')]+=1
        for i in range(26):
            # diff += dict[i] if dict[i]>0 else -dict[i]
            if(dict[i]!=0):
                diff+=1

        if(diff==0):
            return True

        for i in range(m,n):
            a=ord(s2[i])-ord('a')
            b=ord(s2[i-m])-ord('a')
            if(a==b):
                continue

            if(dict[a]==0):
                diff+=1
            dict[a]+=1
            if(dict[a]==0):
                diff-=1

            if(dict[b]==0):
                diff+=1
            dict[b]-=1
            if(dict[b]==0):
                diff-=1
                
            if(diff==0):
                return True
        return False
思路二 双指针

和滑动窗口优化思路相似,首先遍历一遍s1,把s1中出现的字符在cnt数组中--。再遍历一遍s2,对于s2中出现的字符在cnt数组中++。如果出现cnt[x]大于0,就移动左指针,直到cnt[x]<=0。完成这些操作之后,如果right-left+1==n,那么这就是我们要找的子串。

代码二
class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        m,n=len(s1),len(s2)
        cnt=[0]*26
        for i in range(m):
            cnt[ord(s1[i])-ord('a')]-=1
        left,right = 0,0
        while(right0):
                cnt[ord(s2[left])-ord('a')]-=1
                left+=1
            if(right-left+1 == m):
                return True
            right+=1
        return False

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5714144.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存