题目:
给定两个字符串
s1
和s2
,写一个函数来判断s2
是否包含s1
的某个变位词。换句话说,第一个字符串的排列之一是第二个字符串的 子串 。
示例 1:
输入: s1 = "ab" s2 = "eidbaooo" 输出: True 解释: s2 包含 s1 的排列之一 ("ba").
leetcode题目连接:力扣
分析:
变位词是指每个字母出现频率相同但顺序可以不同的词,因此可以用哈希表来存储每个字母出现的频数,由于可以将英文字母可以转化为数字,因此可用数组来替代哈希表;英文字母转化为数字:每个字母对应一个ASCII码,将字母-’a’可转化为数字;由于都是小写字母只有26个,因此可以建立长度为26的数组。
这里可以使用一个长度为s1长度的滑动窗口进行遍历,若s2包含s1,则应出现滑动窗口内哈希表与s2相同的情况,否则不包含。
在向右滑动过程涉及添加元素和减去元素,为了方便可以分为两步,小于s2长度时只涉及添加,大于s2长度时有添加也有删去。
Java代码实现:
class Solution {
public boolean checkInclusion(String s1, String s2) {
int n = s1.length();
int m = s2.length();
if(n>m){ //单独考虑s1大于s2的情况
return false;
}
int[] cnt1 = new int[26];
int[] cnt2 = new int[26];
for(int i = 0; i < n; i++){ //小于等于s1时
++cnt1[s1.charAt(i)-'a'];
++cnt2[s2.charAt(i)-'a'];
}
if(Arrays.equals(cnt1,cnt2)){
return true;
}
for(int i = n; i < m; i++){ //大于s1时
++cnt2[s2.charAt(i)-'a'];
--cnt2[s2.charAt(i-n)-'a'];
if(Arrays.equals(cnt1,cnt2)){
return true;
}
}
return false;
}
}
复杂度分析:
时间复杂度:O(m+n),扫描了s1和s2各一次
空间复杂度:O(1),建立了一个长度为26的数组,不会随输入字符串长度变化而变化
代码执行结果:
以上为个人做题笔记,很多是自己的理解,若有错误还请各位大佬指出~