438. 找到字串中所有字母異位詞(暴力,雙指標)2
阿新 • • 發佈:2020-12-17
技術標籤:LeetCode
給定一個字串s和一個非空字串p,找到s中所有是p的字母異位詞的子串,返回這些子串的起始索引。
字串只包含小寫英文字母,並且字串s和 p的長度都不超過 20100。
說明:
字母異位詞指字母相同,但排列不同的字串。
不考慮答案輸出的順序。
示例1:
輸入:
s: "cbaebabacd" p: "abc"
輸出:
[0, 6]
解釋:
起始索引等於 0 的子串是 "cba", 它是 "abc" 的字母異位詞。
起始索引等於 6 的子串是 "bac", 它是 "abc" 的字母異位詞。
輸入:
s: "abab" p: "ab"
輸出:
[0, 1, 2]
解釋:
起始索引等於 0 的子串是 "ab", 它是 "ab" 的字母異位詞。
起始索引等於 1 的子串是 "ba", 它是 "ab" 的字母異位詞。
起始索引等於 2 的子串是 "ab", 它是 "ab" 的字母異位詞。
解法一:滑動視窗
class Solution { public List<Integer> findAnagrams(String s, String p) { // 先對目標串p每個字元進行字元計數,統計出每個字元的出現次數 int pLength = p.length(); int sLength = s.length(); int[] counts = new int[26]; for(int i = 0; i < pLength; i++){ counts[p.charAt(i) - 'a']++; } ArrayList<Integer> res = new ArrayList<>(); // 儲存結果的結果集 int[] tempCounts = new int[26]; // 記錄視窗內每種字元的出現次數 int left = 0, right = 0; while(right < sLength){ int curR = s.charAt(right) - 'a'; tempCounts[curR]++; // curR字元的出現次數加一 right++; // 新增一個字元後,視窗右指標右移一位 while(tempCounts[curR] > counts[curR]){ // 不斷縮小視窗大小,直到把超標字元移出去一個,使得不超標 tempCounts[s.charAt(left) - 'a']--; left++; // 移走一個字元後窗口左指標右移一位 } if(right - left == pLength){ res.add(left); } } return res; } }