给定两个字符串 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 * 104
s
和p
仅包含小写字母
注意:本题与主站 438 题相同: https://leetcode.cn/problems/find-all-anagrams-in-a-string/
和上一题一样的思路,利用固定长度滑动窗口
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
m, n = len(s), len(p)
if n > m:
return []
window, ans = [0 for _ in range(26)], []
for i in range(n):
window[ord(p[i]) - ord('a')] += 1
window[ord(s[i]) - ord('a')] -= 1
if self.check(window):
ans.append(0)
for i in range(n, m):
window[ord(s[i]) - ord('a')] -= 1
window[ord(s[i - n]) - ord('a')] += 1
if self.check(window):
ans.append(i - n + 1)
return ans
def check(self, window: List[int]) -> bool:
return all([cnt == 0 for cnt in window])
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> ans = new ArrayList<>();
int m = s.length(), n = p.length();
if (n > m) {
return ans;
}
int[] window = new int[26];
for (int i = 0; i < n; i++) {
window[p.charAt(i) - 'a']++;
window[s.charAt(i) - 'a']--;
}
if (check(window)) {
ans.add(0);
}
for (int i = n; i < m; i++) {
window[s.charAt(i) - 'a']--;
window[s.charAt(i - n) - 'a']++;
if (check(window)) {
ans.add(i - n + 1);
}
}
return ans;
}
private boolean check(int[] window) {
return Arrays.stream(window).allMatch(cnt -> cnt == 0);
}
}
func findAnagrams(s string, p string) []int {
m, n := len(s), len(p)
if n > m {
return []int{}
}
ans := make([]int, 0)
window := make([]int, 26)
for i := 0; i < n; i++ {
window[p[i]-'a']++
window[s[i]-'a']--
}
if check(window) {
ans = append(ans, 0)
}
for i := n; i < m; i++ {
window[s[i]-'a']--
window[s[i-n]-'a']++
if check(window) {
ans = append(ans, i-n+1)
}
}
return ans
}
func check(window []int) bool {
for _, cnt := range window {
if cnt != 0 {
return false
}
}
return true
}
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> res;
vector<int> hash(26, 0), zero(26, 0);
if (p.size() > s.size())
return res;
for (int i = 0; i < p.size(); i++) {
hash[p[i] - 'a']++;
hash[s[i] - 'a']--;
}
if (hash == zero)
res.push_back(0);
for (int i = p.size(); i < s.size(); i++) {
hash[s[i] - 'a']--;
hash[s[i - p.size()] - 'a']++;
if (hash == zero)
res.push_back(i - p.size() + 1);
}
return res;
}
};