找到字符串中所有字母异位词
给定两个字符串 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 * 10^4 s 和 p 仅包含小写字母
第一次解答:滑动窗口 + 排序对比
解题思路
核心方法:滑动窗口 + 排序对比。通过固定长度的滑动窗口遍历 s 的所有子串,将子串和 p 分别排序后对比是否相等,以此判断是否为异位词,逻辑直观但时间效率极低。
具体步骤:
- 初始化结果列表
result,用于存储符合条件的子串起始索引。 - 定义滑动窗口的左右边界:
left初始为 0,right初始为 p 的长度(窗口长度固定为 p 的长度,因为异位词长度必与 p 相同)。 - 预处理 p 字符串:将 p 转为字符数组并排序(
Arrays.sort(pArray)),得到 p 的'标准有序形式'(异位词排序后结果相同)。 - 滑动窗口遍历 s 字符串(终止条件:
right <= s.length()): a. 截取当前窗口内的子串s1 = s.substring(left, right); b. 将 s1 转为字符数组并排序(Arrays.sort(s1Array)); c. 对比排序后的 s1 数组和 p 数组是否相等:若相等,说明当前子串是 p 的异位词,将left加入结果列表; d. 窗口右移:left++、right++,继续检查下一个窗口。 - 遍历完成后,返回结果列表
result。
public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<>();
int left = 0;
int right = p.length();
char[] pArray = p.toCharArray();
Arrays.sort(pArray);
while (right <= s.length()) {
String s1 = s.substring(left, right);
char[] s1Array = s1.toCharArray();
Arrays.sort(s1Array);
(Arrays.equals(pArray, s1Array)) {
result.add(left);
}
left++;
right++;
}
result;
}

