力扣
思路一 滑动窗口变位词就是字符串中每个字符出现的次数都相同,但是排列顺序不同。统计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; vectorhash1(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 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)