438. 找到字符串中所有字母异位词
思路
滑动窗口 + 数组(字符计数)
-
使用两个固定长度的数组(长度为 26,代表英文字母 a-z)分别记录:
-
p中各字符的频率; - 当前窗口中各字符的频率;
-
-
遍历
s,滑动长度为len(p)的窗口,比较窗口内字符频率是否与p的一致; -
如果一致,记录窗口起始索引。
复杂度分析
- 时间复杂度:O(n),其中 n 是字符串
s的长度; - 空间复杂度:O(1),因为字符集是固定的(26个字母)。
代码
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
int sLen = s.length();
int pLen = p.length();
if (pLen > sLen) {
return res;
}
// 使用26长度的数组存放字母个数
int[] pCount = new int[26]; // p的字符统计
int[] wCount = new int[26]; // 滑动窗口的字符统计
// 初始化 p 的字符计数
for (char pChar : p.toCharArray()) {
pCount[pChar - 'a']++;
}
// 先统计第一个窗口
for (int i = 0; i < pLen; i++) {
wCount[s.charAt(i) - 'a']++;
}
if (Arrays.equals(pCount, wCount)) {
res.add(0);
}
for (int right = pLen; right < sLen; right++) {
// 左边界的字符(即将移出窗口的字符)
char leftChar = s.charAt(right - pLen);
// 右边界的字符(即将移入窗口的字符)
char rightChar = s.charAt(right);
wCount[leftChar - 'a']--;
wCount[rightChar - 'a']++;
// 窗口的起始索引
int startIndex = right - pLen + 1;
if (Arrays.equals(pCount, wCount)) {
res.add(startIndex);
}
}
return res;
}
}

浙公网安备 33010602011771号