

从您上传的图片中,我看到核心内容是滑动窗口算法在字符串问题中的应用 ,具体问题是**"找到字符串中所有字母异位词"**。以下是针对该问题的完整解析和答案:
问题描述
给定两个字符串 s和 p,在 s中找到所有是 p的字母异位词的子串,返回这些子串的起始索引(顺序任意)。
-
字母异位词 :由相同字母重排形成的字符串,包括
p本身。 -
示例:
s = "cbaebabacd",p = "abc",应返回[0, 6](因为以索引0开始的"cba"和以索引6开始的"bac"都是"abc"的异位词)。
算法原理与思路
1. 暴力法(低效,不推荐)
-
枚举
s中所有长度为m(p的长度)的子串,判断每个子串是否为p的异位词。 -
判断方法:用哈希表统计子串和
p的字符频次,比较是否一致。 -
时间复杂度:O(n × m),效率低。
2. 优化:滑动窗口 + 哈希表(推荐)
-
核心思想 :用固定长度的窗口在
s上滑动,用数组(或哈希表)动态维护窗口内字符频次,与p的频次对比,避免重复计算。 -
为什么用数组 :如果字符串只包含小写字母,可用长度26的数组代替哈希表,下标
index = ch - 'a',提升效率。 -
步骤:
-
统计
p的字符频次,存入数组hash1(长度26)。 -
用另一个数组
hash2统计滑动窗口内字符频次。 -
使用双指针
left和right表示窗口左右边界,初始化left = 0。 -
遍历
s(right从0到n-1):-
进窗口 :将
s[right]加入hash2,并更新有效字符计数count。 -
判断窗口大小 :当窗口长度
right - left + 1 > m时,需要收缩窗口(left++)。 -
出窗口 :移动
left前,从hash2中移除s[left],并更新count。 -
更新结果 :当
count == m时,说明当前窗口是p的异位词,记录left。
-
-
-
有效字符计数
count的作用:-
当窗口内某个字符的频次不超过
p中该字符的频次时,视作有效字符,count++。 -
这样可以用
count == m快速判断窗口是否匹配,无需遍历整个hash2比较。
-
代码实现(Java)
参考图片中的代码片段,以下是完整实现:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<>();
if (s == null || p == null || s.length() < p.length()) {
return result;
}
int n = s.length();
int m = p.length();
// 统计p的字符频次
int[] hash1 = new int[26];
for (char ch : p.toCharArray()) {
hash1[ch - 'a']++;
}
// 滑动窗口的字符频次
int[] hash2 = new int[26];
int count = 0; // 有效字符计数
int left = 0;
for (int right = 0; right < n; right++) {
// 1. 进窗口:当前字符s[right]
char in = s.charAt(right);
hash2[in - 'a']++;
if (hash2[in - 'a'] <= hash1[in - 'a']) {
count++; // 是有效字符
}
// 2. 判断窗口大小是否超过m
if (right - left + 1 > m) {
char out = s.charAt(left);
// 出窗口前,如果out是有效字符,则count--
if (hash2[out - 'a'] <= hash1[out - 'a']) {
count--;
}
hash2[out - 'a']--; // 移除字符
left++; // 左指针右移
}
// 3. 更新结果:当有效字符数等于m时,记录起始索引left
if (count == m) {
result.add(left);
}
}
return result;
}
}
时间复杂度与空间复杂度
-
时间复杂度 :O(n),其中 n 是字符串
s的长度。每个字符最多进入和离开窗口各一次,操作是 O(1)。 -
空间复杂度:O(1),因为哈希数组大小固定为26,与输入规模无关。
关键点总结
-
滑动窗口固定长度 :窗口大小始终为
m(p的长度),通过双指针left和right同步滑动。 -
有效字符计数 :用
count跟踪窗口内与p匹配的字符个数,避免每次比较整个数组。 -
数组代替哈希表 :针对小写字母场景,数组更高效;如果字符集扩大,可改用
HashMap。
此算法高效且易于实现,是解决"字母异位词子串"问题的标准方法。