剑指 Offer II 014. 字符串中的变位词
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的某个变位词。
换句话说,第一个字符串的排列之一是第二个字符串的 子串 。
示例 1:
输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).
示例 2:
输入: s1= “ab” s2 = “eidboaoo”
输出: False
提示:
1 <= s1.length, s2.length <= 104
s1 和 s2 仅包含小写字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/MPnaiL
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析
1、创建一个代表26个字母的容量26的数组counts(哈希表);
2、先按照短字符串s1的长度遍历,s1中出现的字符++,s2中对应索引出现的字符–;
3、遍历完之后调用判断counts是否全为0的方法,如果全为0则返回true,如果不是全为0,继续遍历长字符串s2后面的字符;
4、对s2后面出现的字符–,同时对s2最前面的字符++(这里相当于双指针),对这个操作进行一个解释:由于在第2步中对s2最前面的字符进行过–操作,在这一步中对最前面的字符++操作可以抵消第2步对应索引的操作,同理如果s2的长度是s1的两倍以上,这一步中“对s2后面出现的字符–”也可以抵消掉。
题解(Java)
class Solution {
public boolean checkInclusion(String s1, String s2) {
if (s1.length() > s2.length()) return false;
int[] counts = new int[26];
for (int i = 0; i < s1.length(); i++) {
counts[s1.charAt(i) - 'a']++;
counts[s2.charAt(i) - 'a']--;
}
if (judgeZero(counts)) return true;
for (int i = s1.length(); i < s2.length(); i++) {
counts[s2.charAt(i) - 'a']--;
counts[s2.charAt(i - s1.length()) - 'a']++;
if (judgeZero(counts)) return true;
}
return false;
}
private boolean judgeZero(int[] counts) {
for (int count : counts) {
if (count != 0) return false;
}
return true;
}
}