栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

剑指 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
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/717824.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号