给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的某个变位词。换句话说,第一个字符串的排列之一是第二个字符串的子串 。
解题思路:
滑动窗口法:设置两个指针,right往右移动,当滑动时在s2上截取的长度大于s1的长度时left就向右移动。本解法只使用了一个int[26]的数组。代码如下:
public boolean checkInclusion(String s1, String s2) {
int n = s2.length();
int m = s1.length();
int[] tempS1 = new int[26];
//将s1每个位统计
for(char c: s1.toCharArray()){
tempS1[c - 'a']--;
}
int left = 0;
for(int right = 0;right<n;right++){
tempS1[s2.charAt(right) - 'a']++;
while(tempS1[s2.charAt(right) - 'a'] > 0){
tempS1[s2.charAt(left) - 'a']--;
left++;
}
if(right - left + 1 == m){
return true;
}
}
return false;
}
同理:
给定两个字符串 s
和 p
,找到 s
中所有 p
的 变位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。解法相同。代码如下:
public List<Integer> findAnagrams(String s, String p) {
int m = p.length();
int[] temp = new int[26];
for(char c: p.toCharArray()){
temp[c - 'a']--;
}
List<Integer> res = new ArrayList<>();
int left = 0;
for(int right =0;right<s.length();right++){
temp[s.charAt(right) - 'a']++;
while(temp[s.charAt(right) - 'a'] > 0){
temp[s.charAt(left) - 'a']--;
left++;
}
if(right - left + 1 == m){
res.add(left);
}
}
return res;
}