给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
异位词指由相同字母重排列形成的字符串(包括相同的字符串)。
示例 1:
输入: s = “cbaebabacd”, p = “abc”
输出: [0,6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的异位词。
示例 2:
输入: s = “abab”, p = “ab”
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的异位词。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的异位词。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的异位词。
提示:
1 <= s.length, p.length <= 3 * 104
s 和 p 仅包含小写字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string
(1)滑动窗口
此题与LeetCode_滑动窗口_困难_76.最小覆盖子串类似,只不过是找到一个合法异位词(排列)之后将起始索引加入 res 即可。
//思路1————滑动窗口
public List<Integer> findAnagrams(String s, String p) {
int sLen = s.length();
int pLen = p.length();
//res用于保存结果
List<Integer> res = new ArrayList<>();
HashMap<Character, Integer> window = new HashMap<Character, Integer>();
HashMap<Character, Integer> need = new HashMap<Character, Integer>();
//将字符串p中的字符存入哈希表need中,key/value为字符/出现的次数
for(int i=0;i<p.length();i++){
char c = p.charAt(i);
need.put(c, need.getOrDefault(c,0) + 1);
}
int left = 0,right = 0;
//valid记录窗口中p中不重复字符的个数
int valid = 0;
while(right < sLen){
char c = s.charAt(right);
right++;
//更新窗口内的数据
//如果字符c存在于p中,则将其加入到window中
if(need.containsKey(c)){
window.put(c, window.getOrDefault(c,0) + 1);
//p中的字符c已经全部加入到window中
if(window.get(c).equals(need.get(c))){
valid++;
}
}
//判断左侧窗口是否要收缩
while(right - left >= pLen){
//p中的所有字符都已经加入到窗口中
if(valid == need.size()){
res.add(left);
}
//d是即将移出窗口的字符
char d = s.charAt(left);
left++;
//更新窗口内的数据
if(need.containsKey(d)){
if(window.get(d).equals(need.get(d))){
valid--;
}
window.put(d,window.get(d)-1);
}
}
}
return res;
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_43004044/article/details/122446208
内容来源于网络,如有侵权,请联系作者删除!