438. Find All Anagrams in a String

Posted ruruozhenhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了438. Find All Anagrams in a String相关的知识,希望对你有一定的参考价值。

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".

Approach #1: C++. Using sort and substr[Time Limit Exceeded]

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int> ans;
        if (s.length() < p.length()) return ans;
        sort(p.begin(), p.end());
        int len = p.size();
        for (int i = 0; i < s.length()-len+1; ++i) {
            string temp = s.substr(i, len);
            sort(temp.begin(), temp.end());
            if (temp == p) ans.push_back(i);
        }
        return ans;
    }
};

  

Approach #2:  C++. Using sliding windows.

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        unordered_map<char, int> mp;
        vector<int> ans;
        
        for (int i = 0; i < p.length(); ++i) {
            mp[p[i]]++;
        }
        
        int begin = 0, end = 0;
        int counter = mp.size();
        
        while (end < s.length()) {
            char tempc = s[end];
            if (mp.count(tempc)) {
                mp[tempc]--;
                if (mp[tempc] == 0) counter--;
            }
            
            end++;
            
            while (counter == 0) {
                char tempc = s[begin];
                if (mp.count(tempc)) {
                    mp[tempc]++;
                    if (mp[tempc] > 0) counter++;
                }
                if (end - begin == p.length()) {
                    ans.push_back(begin);
                }
                begin++;
            }
        }
        return ans;
    }
};

  

Approach #3: Java. 

class Solution {
    public List<Integer> findAnagrams(String s, String t) {
        List<Integer> result = new LinkedList<>();
        if (t.length() > s.length()) return result;
        Map<Character, Integer> map = new HashMap<>();
        for (char c : t.toCharArray()) {
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        int counter = map.size();
        
        int begin = 0, end = 0;
        int head = 0;
        int len = Integer.MAX_VALUE;
        
        while (end < s.length()) {
            char c = s.charAt(end);
            if (map.containsKey(c)) {
                map.put(c, map.get(c) - 1);
                if (map.get(c) == 0) counter--;
            }
            end++;
            while (counter == 0) {
                char tempc = s.charAt(begin);
                if (map.containsKey(tempc)) {
                    map.put(tempc, map.get(tempc) + 1);
                    if (map.get(tempc) > 0) {
                        counter++;
                    }
                }
                if (end-begin == t.length()) {
                    result.add(begin);
                }
                begin++;
            }
        }
        return result;
    }
}

  

Approach #4: Python.

from collections import Counter

class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        res = []
        pCounter = Counter(p)
        sCounter = Counter(s[:len(p)-1])
        for i in range(len(p)-1, len(s)):
            sCounter[s[i]] += 1
            if sCounter == pCounter:
                res.append(i-len(p)+1)
            sCounter[s[i-len(p)+1]] -= 1
            if sCounter[s[i-len(p)+1]] == 0:
                del sCounter[s[i-len(p)+1]]
        return res

  

Time SubmittedStatusRuntimeLanguage
a few seconds ago Accepted 240 ms python
43 minutes ago Accepted 44 ms cpp
an hour ago Accepted 61 ms java

 

以上是关于438. Find All Anagrams in a String的主要内容,如果未能解决你的问题,请参考以下文章

438. Find All Anagrams in a String

438. Find All Anagrams in a String

Leetcode 438. Find All Anagrams in s String

[leetcode-438-Find All Anagrams in a String]

438. Find All Anagrams in a String

438. Find All Anagrams in a String