给定两个字符串 s
和 p
,找到 s
中所有 p
的 变位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
变位词 指字母相同,但排列不同的字符串。
class Solution {
public List<Integer> findAnagrams(String s, String p) {
int sLen = s.length(), pLen = p.length();
if (sLen < pLen) {
return new ArrayList<Integer>();
}
List<Integer> ans = new ArrayList<Integer>();
int[] sCount = new int[26];
int[] pCount = new int[26];
for (int i = 0; i < pLen; ++i) {
++sCount[s.charAt(i) - 'a'];
++pCount[p.charAt(i) - 'a'];
}
if (Arrays.equals(sCount, pCount)) {
ans.add(0);
}
for (int i = 0; i < sLen - pLen; ++i) {
--sCount[s.charAt(i) - 'a'];
++sCount[s.charAt(i + pLen) - 'a'];
if (Arrays.equals(sCount, pCount)) {
ans.add(i + 1);
}
}
return ans;
}
}
来源:力扣(LeetCode)
- 首先,定义了一个
Solution
类,并在其中定义了一个名为findAnagrams
的公共方法,该方法接收两个字符串参数:s
和p
。 - 然后,获取
s
和p
的长度,并存储在sLen
和pLen
中。 - 如果
s
的长度小于p
的长度,那么显然s
中不可能包含p
的异位词,因此直接返回一个空的ArrayList。 - 创建一个空的ArrayList
ans
,用于存储找到的异位词的起始索引。 - 定义两个整型数组
sCount
和pCount
,长度为26(因为英文字母有26个)。这两个数组用于存储字符串s
和p
中每个字母出现的次数。 - 遍历字符串
p
,对p
中的每个字符,增加其在pCount
数组中的计数。 - 遍历字符串
s
的前pLen
个字符(即s
的前p
长度的子串),对每个字符,增加其在sCount
数组中的计数。 - 使用
Arrays.equals
方法比较sCount
和pCount
数组。如果相等,说明s
的前p
长度的子串是p
的异位词,将0(即这个子串在s
中的起始索引)添加到ans
中。 - 接着,对
s
中的每个子串(长度为pLen
,且起始位置从0到sLen - pLen
)进行遍历。对于每个子串,先减少子串开始字符在sCount
中的计数,然后增加子串结束字符的下一个字符在sCount
中的计数。 - 每次修改
sCount
后,都检查sCount
是否等于pCount
。如果相等,说明当前子串是p
的异位词,将其起始索引(当前遍历的起始位置加1)添加到ans
中。 - 最后,返回
ans
,即所有找到的异位词的起始索引。