Find All Anagrams in a String
Given two strings spps
An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
Example 1
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
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".
Constraints:
1 <= s.length, p.length <= 3 * 104 ands consist of lowercase English letters.p
Solution 1 - Using sliding window technique, maintain characters count from String 's' and check against characters count from String 'p'
In this approach, we are going to store characters count from string pHashMapsp
Implementation steps:
-
Initialize two
's,HashMap to store characters count from stringp_count andp to store characters count froms_count .s -
Then, loop through characters of
and store them ins , when the window size (number of characters have read from strings_count ) are of same length as strings 's length, then check if bothp 's have same characters and their count, if they are add the starting index of current window to result.HashMap -
When we move slide to next character, i.e. remove window starting indexed character and add next character to
, if the character count become zero after decrementing window starting indexed letter we will remove that entry froms_count .s_count
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class FindAllAnagrams {
static List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<>();
if(p.length() > s.length()) {
return result;
}
HashMap<Character, Integer> p_count = new HashMap<>();
HashMap<Character, Integer> s_count = new HashMap<>();
for(int i=0; i<p.length() -1 ; i++) {
p_count.merge(p.charAt(i), 1, Integer::sum);
s_count.merge(s.charAt(i), 1, Integer::sum);
}
p_count.merge(p.charAt(p.length()-1), 1, Integer::sum);
for(int i=p.length() -1; i<s.length(); i++) {
//add next character to current slide window to make s_count and p_count have same number of characters
s_count.merge(s.charAt(i), 1, Integer::sum);
int windowStart = i - p.length() +1;
if(p_count.equals(s_count)) {
result.add(windowStart);
}
//Now, remove beginning indexed character to move the sliding window
Integer valAfter = s_count.merge(s.charAt(windowStart), -1, Integer::sum);
if(valAfter.equals(0)) {
s_count.remove(s.charAt(windowStart));
}
}
return result;
}
public static void main(String[] args) {
System.out.println(findAnagrams("cbaebabacd", "abc"));
System.out.println(findAnagrams("abab", "ab"));
System.out.println(findAnagrams("baa", "aa"));
System.out.println(findAnagrams("aaaaaaaaaa", "aaaaaaaaaaaaa"));
}
}
Complexity Analysis:
Time complexity: Above code runs in O(n) time where nssp
Space complexity: O(1), though we are storing characters count into HashMap
Above implementations source code can be found at