leetcode 438

Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

The order of output does not matter. Example 1:

Input: s: "cbaebabacd" p: "abc" Output: [0, 6] Explanation: The substring with start index = 0 is "cba", which is an anagram of "abc". The substring with start index = 6 is "bac", which is an anagram of "abc".

Example 2:

Input: s: "abab" p: "ab" Output: [0, 1, 2] Explanation: The substring with start index = 0 is "ab", which is an anagram of "ab". The substring with start index = 1 is "ba", which is an anagram of "ab". The substring with start index = 2 is "ab", which is an anagram of "ab".

解题 :比较容易想到的解法就是window slide, 用一个和p 大小一样的queue来维护一个window,来比较两个字符串是不是anagrams。但是那样是时间复杂度是o(n*m),我们可以用两个pointer来达到o(n)解法,首先我们要有个map,这里用了数组sum,如果需要考虑其他字符就设置为256长度。然后把字符串p里面的字符出现频率放进sum里面。 用一个start指针,一个end指针分别指向window两端,end需要处理看新加入的字符是否在map里面,如果在我们就把matched count加1,然后把map里面对应count减1. start需要每次调整match count和map里面的count。

class Solution {
        public List<Integer> findAnagrams(String s, String p) {
        // Write your code here
        List<Integer> ans = new ArrayList<Integer>();
        int[] sum = new int[30];

            int pLen = p.length();
            int sLen = s.length();
            for (char c : p.toCharArray()) {
                sum[c - 'a']++;
            }

            int start = 0, end = 0, matched = 0;
            while (end < sLen) {
                //first part deal end pointer, if there is match in end, matched++ and move the count in sum
                if (sum[s.charAt(end) - 'a'] >= 1) {
                    matched++;
                }
                sum[s.charAt(end) - 'a']--;
                end++;

                //when we find a match
                if (matched == pLen) {
                    ans.add(start);
                }

                //deal start index, move the window
                if (end - start == pLen) {
                    if (sum[s.charAt(start) - 'a'] >= 0) {
                        matched --;
                    }
                    //put the count back
                    sum[s.charAt(start) - 'a']++;
                    start++;
                }

            }
        return ans;
    }
}

results matching ""

    No results matching ""