题解:滑动窗口(双指针)
思路:
这段Java代码的思路是使用两个哈希表(HashMap)来寻找字符串s中所有字符串p的异位词的子串,并返回这些子串的起始索引。以下是代码的详细思路:
- 初始化:
- 创建一个列表
list
来存储所有异位词子串的起始索引。 - 创建两个哈希表
hashS
和hashP
,分别用于存储字符串s的当前窗口中的字符频率和字符串p的字符频率。
- 创建一个列表
- 填充哈希表
hashP
:- 遍历字符串p中的每个字符,将字符作为键,字符出现的次数作为值,填充哈希表
hashP
。
- 遍历字符串p中的每个字符,将字符作为键,字符出现的次数作为值,填充哈希表
- 边界检查:
- 如果字符串s的长度小于字符串p的长度,则不可能存在异位词,直接返回空列表。
- 滑动窗口:
- 使用两个指针
fast
和slow
来表示滑动窗口的右边界和左边界。 - 当
fast
指针小于字符串s的长度时,执行以下步骤:- 将
fast
指针指向的字符加入到hashS
中,并更新字符的频率。 - 增加
fast
指针,扩大窗口。 - 当窗口大小等于字符串p的长度时(即
fast - slow == p.length()
),执行以下步骤:- 比较两个哈希表
hashS
和hashP
是否相等。如果相等,说明找到了一个异位词,将slow
指针的值加入到列表list
中。 - 减少窗口左边界
slow
指向的字符在hashS
中的频率。 - 如果该字符的频率变为0,则从
hashS
中移除该键值对。 - 增加
slow
指针,缩小窗口。
- 比较两个哈希表
- 将
- 使用两个指针
- 返回结果:
- 在滑动窗口的过程中,记录所有满足条件的窗口起始索引,最后返回列表
list
。
代码通过维护两个哈希表来跟踪当前窗口和字符串p中字符的频率,并通过滑动窗口的方式检查每个窗口是否是字符串p的异位词。当找到异位词时,将窗口的起始索引添加到结果列表中。
- 在滑动窗口的过程中,记录所有满足条件的窗口起始索引,最后返回列表
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> list = new ArrayList<>();
HashMap<Character,Integer> hashS = new HashMap<>();
HashMap<Character,Integer> hashP = new HashMap<>();
for(char str : p.toCharArray()){
hashP.put(str, hashP.getOrDefault(str, 0) + 1);
}
if(s.length() < p.length()){
return list;
}
int fast = 0;
int slow = 0;
while(fast < s.length()){
hashS.put(s.charAt(fast), hashS.getOrDefault(s.charAt(fast), 0) + 1);
fast++;
if(fast - slow == p.length()){
if(hashS.equals(hashP)){
list.add(slow);
}
hashS.put(s.charAt(slow), hashS.get(s.charAt(slow)) - 1);
if(hashS.get(s.charAt(slow)) == 0){
hashS.remove(s.charAt(slow));
}
slow++;
}
}
return list;
}
}