LeetCode 438 找到字串中所有字母異位詞
阿新 • • 發佈:2021-11-29
給定兩個字串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
僅包含小寫字母
滑動視窗+ 雙指標
/** * 雙指標,滑動視窗 * @param s * @param p * @return */ public static List<Integer> findAnagrams(String s, String p) { List<Integer> ans = new ArrayList<>(); int n = s.length(), m = p.length(); // 分別記錄一段範圍內的字元出現的次數 int[] c1 = new int[26], c2 = new int[26]; for (int i = 0; i < m; i++) c2[p.charAt(i) - 'a']++; // l,r分別表示滑動視窗兩端的下標 for (int l = 0, r = 0; r < n; r++) { // 加入滑動視窗內 c1[s.charAt(r) - 'a']++; // 移除滑動視窗的第一個元素 if (r - l + 1 > m) c1[s.charAt(l++) - 'a']--; // 檢測是否匹配 if (check(c1, c2)) ans.add(l); } return ans; } static boolean check(int[] c1, int[] c2) { for (int i = 0; i < 26; i++) { if (c1[i] != c2[i]) return false; } return true; }
測試用例
public static void main(String[] args) { String s = "cbaebabacd"; String p = "abc"; List<Integer> integerList = FindAnagrams.findAnagrams(s, p); System.out.println("FindAnagrams demo01 result : "); for (Integer integer : integerList) { System.out.print(" " + integer); } System.out.println(""); s = "abab"; p = "ab"; integerList = FindAnagrams.findAnagrams(s, p); System.out.println("FindAnagrams demo02 result : "); for (Integer integer : integerList) { System.out.print(" " + integer); } System.out.println(""); }
測試結果
FindAnagrams demo01 result :
0 6
FindAnagrams demo02 result :
0 1 2