Find All Anagrams in a String

Problem

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

Solution

Sliding Window with Super Concise Code: O(n) time

public class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();
        if (s == null || p == null || s.length() < p.length()) return res;
        int[] hashP = new int[256];
        for (char c : p.toCharArray()) hashP[c]++;
        int left = 0, right = 0, count = p.length();
        while (right < s.length()) {
            if (hashP[s.charAt(right++)]-- > 0) count--;
            if (count == 0) res.add(left);
            if (right - left == p.length() && hashP[s.charAt(left++)]++ >= 0) count++; //>=0 means it exists in p 
        }
        return res;
    }
}

Analysis

The solution above uses Sliding Window
We have two var left and right to check through the string s
We first move the right and decrease hashP with index s.charAt(right)
If the result is > 0, which means the character exists in hashP
We update count--
Then as long as the count == 0 we know we find an anagram so that we add left to our result
If the size of window right - left == p.length(), we recover the hashP with index left++
If the result >= 0, we know that that character originally exists in hashP
Otherwise it won't go below than 0, hence we recover count++

results matching ""

    No results matching ""