找到字符串中所有字母异位词
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 47 ms, 内存: 16.6 MB
// 思路:
// 使用滑动窗口和Java Stream来寻找s中所有p的变位词的子串。
// 1. 计算p中每个字符的出现次数,存储在一个计数数组中。
// 2. 初始化一个窗口,窗口大小为p的长度,并计算窗口中每个字符的出现次数。
// 3. 滑动窗口,每次移动一个字符,并更新窗口中字符的计数。
// 4. 如果窗口中的字符计数与p中的字符计数匹配,则记录起始索引。
import java.util.*;
import java.util.stream.*;
public class Solution {
public List<Integer> findAnagrams(String s, String p) {
if (s == null || p == null || s.length() < p.length()) return Collections.emptyList();
int[] pCount = new int[26];
int[] sCount = new int[26];
for (char c : p.toCharArray()) {
pCount[c - 'a']++;
}
return IntStream.range(0, s.length())
.mapToObj(i -> {
sCount[s.charAt(i) - 'a']++;
if (i >= p.length()) {
sCount[s.charAt(i - p.length()) - 'a']--;
}
return matches(pCount, sCount) ? i - p.length() + 1 : -1;
})
.filter(index -> index != -1)
.collect(Collectors.toList());
}
private boolean matches(int[] pCount, int[] sCount) {
return IntStream.range(0, 26).allMatch(i -> pCount[i] == sCount[i]);
}
}
解释
方法:
此题解采用滑动窗口和字符频率计数的方法来找出所有的字母异位词的起始索引。首先,如果字符串p的长度大于s,则直接返回空列表,因为s中不可能有p的异位词。然后,使用两个大小为26的数组cnt_s和cnt_p来统计窗口内s的字符频率和字符串p的字符频率。初始窗口大小为p的长度,逐一比较两个计数数组,如果相等,则将当前窗口的起始索引加入结果列表。随后,窗口向右滑动,每次移动更新窗口内的字符频率,继续比较和记录结果。
时间复杂度:
O(m)
空间复杂度:
O(1)
代码细节讲解
🦆
题解中提到使用两个大小为26的数组来统计字符频率,为什么选择数组而不是其他数据结构,例如哈希表?
▷🦆
在滑动窗口中,每次向右移动窗口时只更新一个字符的进入和离开,这种方法有效率提升的原理是什么?
▷🦆
如果输入字符串s包含非小写字母的字符,现有的解决方案还适用吗?
▷