题目:
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。
题解:
滑动窗口算法的代码框架(C++):
/* 滑动窗口算法框架 */
void slidingWindow(string s, string t) {
unordered_map<char, int> need, window;
for (char c : t) need[c]++;
int left = 0, right = 0;
int valid = 0;
while (right < s.size()) {
// c 是将移入窗口的字符
char c = s[right];
// 右移窗口
right++;
// 进行窗口内数据的一系列更新
...
/*** debug 输出的位置 ***/
printf("window: [%d, %d)\n", left, right);
/********************/
// 判断左侧窗口是否要收缩
while (window needs shrink) {
// d 是将移出窗口的字符
char d = s[left];
// 左移窗口
left++;
// 进行窗口内数据的一系列更新
...
}
}
}
完整代码:
注意点:Java中Integer、String之类对象的==判断最好用equals,比如Integer 在大于127 的时候 不从常量池里拿,是个对象。left、right是左闭右开
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
Map<Character, Integer> need = new HashMap<>();
Map<Character, Integer> window = new HashMap<>();
int left = 0, right = 0;
int valid = 0;
for (char c : p.toCharArray()) {
need.put(c, need.getOrDefault(c, 0) + 1);
}
while (right < s.length()) {
char c1 = s.charAt(right);
right++;
// 进行窗口内数据的一系列更新
if (need.containsKey(c1)) {
window.put(c1, window.getOrDefault(c1, 0) + 1);
if (window.get(c1).equals(need.get(c1))) { //Integer 在大于127 的时候 不从常量池里拿,是个对象,所以换成equals
valid++;
}
}
// 判断左侧窗口是否要收缩
//left、right是左闭右开,因此left - right就是窗口长度
while (right - left >= p.length()) {
// 当窗口符合条件时,把起始索引加入 res
if (valid == need.size()) { //注意比较的是need的size
res.add(left);
}
char c2 = s.charAt(left);
left++;
// 进行窗口内数据的一系列更新
if (need.containsKey(c2)) {
if (window.get(c2).equals(need.get(c2))) {
valid--;
}
window.put(c2, window.get(c2)- 1);
}
}
}
return res;
}
}
参考:力扣