👨‍💻
Coding Interview Patterns
  • Coding Interview Patterns
  • 1. Pattern: Sliding Window
    • 1.0 Introduction
    • 1.1 Maximum Sum Subarray of Size K (easy)
    • 1.2 Smallest Subarray with a given sum (easy)
    • 1.3 Longest Substring with K Distinct Characters (medium)
    • 1.4 Fruits into Baskets (medium)
    • 1.5 No-repeat Substring (hard)
    • 1.6 Longest Substring with Same Letters after Replacement (hard)
    • 1.7 Longest Subarray with Ones after Replacement (hard)
    • 1.8 - Permutation in a String (hard)
    • 1.9 String Anagrams (hard)
    • 1.10 Smallest Window containing Substring (hard)
    • 1.11 Words Concatenation (hard)
  • 2. Pattern: Two Pointers
    • 2.0 Introduction
    • 2.1 Pair with Target Sum (easy)
    • 2.2 Remove Duplicates (easy)
    • 2.3 Squaring a Sorted Array (easy)
    • 2.4 Triplet Sum to Zero (medium)
    • 2.5 Triplet Sum Close to Target (medium)
    • 2.6 Triplets with Smaller Sum (medium)
    • 2.7 Subarrays with Product Less than a Target (medium)
    • 2.8 Dutch National Flag Problem (medium)
    • 2.9 Comparing Strings containing Backspaces (medium)
    • 2.10 Minimum Window Sort (medium)
  • 7. Pattern: Tree Breadth First Search
    • 7.0 Introduction
    • 7.1 Binary Tree Level Order Traversal (easy)
    • 7.2 Reverse Level Order Traversal (easy)
    • 7.3 Zigzag Traversal (medium)
    • 7.4 Level Averages in a Binary Tree (easy)
    • 7.5 Minimum Depth of a Binary Tree (easy)
    • 7.6 Maximum Depth of Binary Tree (easy)
    • 7.7 Level Order Successor (easy)
    • 7.8 Connect Level Order Siblings (medium)
    • 7.9 Problem Challenge 1 - Connect All Level Order Siblings (medium)
    • 7.10 Problem Challenge 2 - Right View of a Binary Tree (easy)
  • 11. Pattern: Modified Binary Search
    • 11.1 Introduction
    • 11.2 Order-agnostic Binary Search (easy)
    • 11.3
  • 16. Pattern: Topological Sort (Graph)
    • 16.1 Introduction
    • 16.2 Topological Sort (medium)
    • 16.3 Tasks Scheduling (medium)
    • 16.4 Tasks Scheduling Order (medium)
  • Contributor Covenant Code of Conduct
  • Page 1
Powered by GitBook
On this page

Was this helpful?

  1. 1. Pattern: Sliding Window

1.9 String Anagrams (hard)

Previous1.8 - Permutation in a String (hard)Next1.10 Smallest Window containing Substring (hard)

Last updated 3 years ago

Was this helpful?

Problem:

Given two strings s and p, return an array of all the start indices of p's anagrams in s. You may return the answer in any order.

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

Constraints:

  • 1 <= s.length, p.length <= 3 * 104

  • s and p consist of lowercase English letters.

public class Solution {
    public List<Integer> findAnagrams(String s, String p) {
       ///We will use sliding window template
       
       ArrayList<Integer> soln = new ArrayList<Integer>();
       
       //Check for bad input
       if (s.length() == 0 || p.length() == 0 || s.length() < p.length()){
           return new ArrayList<Integer>();
       }
       
       //Set up character hash
       //Keep track of how many times each character appears
       int[] chars = new int[26];
       for (Character c : p.toCharArray()){
           //Increment to setup hash of all characters currently in the window
           //Later on, these get DECREMENTED when a character is found
           //A positive count later on means that the character is still "needed" in the anagram
           //A negative count means that either the character was found more times than necessary
           //Or that it isn't needed at all
           chars[c-'a']++;
       }
       
       //Start = start poniter, end = end pointer,
       //len = length of anagram to find
       //diff = length of currently found anagram. If it equals
       //the length of anagram to find, it must have been found
       int start = 0, end = 0, len = p.length(), diff = len;
       
       char temp;
       //Before we begin this, the "window" has a length of 0, start and
       //end pointers both at 0
       for (end = 0; end < len; end++){
           //Process current char
           temp = s.charAt(end);
           
           //As discussed earlier, decrement it
           chars[temp-'a']--;
           
           //If it's still >= 0, the anagram still "needed" it so we count it towards the anagram by
           //decrementing diff
           if (chars[temp-'a'] >= 0){
               diff--;
           }
       }
       
       //This would mean that s began with an anagram of p
       if (diff == 0){
           soln.add(0);
       }
       
       //At this point, start remains at 0, end has moved so that the window is the length of the anagram
       //from this point on we are going to be moving start AND end on each iteration, to shift the window
       //along the string
       while (end < s.length()){
           
           //Temp represents the current first character of the window. The character that is
           //going to be "left behind" as the window moves. 
           temp = s.charAt(start);
           
           //If it's not negative, this means that the character WAS part of the anagram. That means we
           //are one step "farther away" from completing an anagram. So we must increment diff.
           if (chars[temp-'a'] >= 0){
               diff++;
           }
           
           //Increment the hash value for this character, because it is no longer contained in the window
           chars[temp-'a']++;
           
           //Increment start to start shifting the window over by 1
           start++;
           
           //Temp represents the last character of the window, the "new" character from the window shift.
           //This character "replaces" the one we removed before so the window stays the same length (p.length())
           temp = s.charAt(end);
           
           //Decrement hash value for this character, because it is now a part of the window
           chars[temp-'a']--;
           
           //Again, if it's not negative it is part of the anagram. So decrement diff
           if (chars[temp-'a'] >= 0){
               diff--;
           }
           
           //If diff has reached zero, that means for the last p.length() iterations, diff was decremented and
           //NOT decremented, which means every one of those characters was in the anagram, so it must be an anagram
           
           //Note: If many windows in a row find anagrams, then each iteration will have diff incremented then decremented again
           if (diff == 0){
               soln.add(start);
           }
           
           //Increment for next iteration
           end++;
           
       }
       
       return soln;
       
       
    }
}
438. Find All Anagrams in a String