438. 找到字符串中所有字母异位词【滑动窗口】
题目
438. 找到字符串中所有字母异位词
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。
示例 1:
输入:
s: "cbaebabacd" p: "abc"
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。
思路
此题也是滑动窗口的题目,一样的套路,写模板,回答问题
扩大窗口需要做什么操作?
什么条件下缩小窗口?
缩小窗口之后做什么操作?
结果在扩大窗口还是缩小窗口处更新?
然后依次填入即可。
扩大窗口需要做什么操作?-----更新windows增加值,判断是windows中和need的的新增值是否相等,相等则计数+1
什么条件下缩小窗口?-----缩小窗口条件为 窗口大小和目标字符串一样大时(为了保证窗口的大小)
缩小窗口之后做什么操作?-----更新windows减少值,判断是windows中和need的的新增值是否相等,相等则计数-1
结果在扩大窗口还是缩小窗口处更新?------因为要子串,所以在缩小窗口之前更新(需要判断下窗口中的计数和need大小是否相等)
class Solution {
public List<Integer> findAnagrams(String s, String p) {
ArrayList<Integer> ret = new ArrayList<>();
HashMap<Character,Integer> windows = new HashMap<>();
HashMap<Character,Integer> need = new HashMap<>();
int left = 0, right = 0;
int vaild = 0;
for (int i = 0; i < p.length(); i++) {
need.put(p.charAt(i), need.getOrDefault(p.charAt(i), 0 )+1);
}
while (right<s.length()){
char c = s.charAt(right);
right++;
windows.put(c, windows.getOrDefault(c, 0)+1);
if(windows.get(c).equals(need.get(c))){
vaild++;
}
while (right-left==p.length()){
if(vaild==need.size()){
ret.add(left);
}
char d = s.charAt(left);
left++;
if(windows.get(d).equals(need.get(d))){
vaild--;
}
windows.put(d, windows.getOrDefault(d,0)-1);
}
}
return ret;
}
}

浙公网安备 33010602011771号