Find All Anagrams In A String

To solve this coding challenge, we need to find all the start indices of the anagrams of string
p
within string
s
. An anagram of a string is formed by rearranging its letters, so for each substring of
s
with the length equal to
p
, we need to check if it is an anagram of
p
.

Explanation

  1. Initial Checks : We begin by checking if
    s
    or
    p
    are empty, or if the length of
    s
    is less than the length of
    p
    . If any of these conditions is true, we return an empty list as it's not possible to have any anagrams.
  2. Initial Setup : We initialize an empty list to store the starting indices of the anagrams. We then count the occurrences of each character in
    p
    (using a dictionary or any other suitable data structure) and do the same for the first
    len(p) - 1
    characters in
    s
    .
  3. Sliding Window : We move a sliding window across
    s
    starting from
    len(p) - 1
    to the end of
    s
    . For each position of the window:
    • Include the character at the current position in our count.
    • Compare the current window's character counts with
      p
      's character counts. If they match, it means we found an anagram starting at the calculated index.
    • Exclude the character that is no longer in the window from our count.
  4. Result Processing : Finally, return the list of starting indices where we found anagrams.
  5. Detailed Steps

  6. Check for Empty Inputs :
    • If
      s
      or
      p
      is empty or
      len(s) < len(p)
      , return an empty list because it is impossible to find any anagrams.
  7. Initialize Result and Counts :
    • Create an empty list
      result
      to store the starting indices of anagrams.
    • Use a dictionary
      p_count
      to store the count of each character in
      p
      .
    • Initialize a dictionary
      s_count
      to store the count of characters in the initial window of
      s
      (first
      len(p) - 1
      characters).
  8. Process Each Window :
    • Iterate from
      len(p) - 1
      to
      len(s)
      .
      • Add the character at the current index to
        s_count
        .
      • Compare
        s_count
        with
        p_count
        . If they are equal, append the starting index of the window to
        result
        .
      • Remove the character that exits the window from
        s_count
        .

    Step-by-Step Explanation

  9. Initial Checks :
    • If
      s
      is empty or
      p
      is empty or the length of
      s
      is less than the length of
      p
      , return an empty list.
  10. Populate
    p_count
    and Initial
    s_count
    :
    • Calculate the frequency of each character in
      p
      and store it in
      p_count
      .
    • For the initial window (
      s[0]
      to
      s[len(p) - 2]
      ), calculate the frequency of each character and store it in
      s_count
      .
  11. Sliding Window Processing :
    • Loop over each character in the string
      s
      starting from the
      len(p) - 1
      index to the end.
    • Add the current character to
      s_count
      .
    • If the current window's character counts (
      s_count
      ) match
      p_count
      , store the starting index of this window in the result list.
    • Remove the character at the start of the previous window from
      s_count
      .
Detailed Steps in Pseudocode:
                                            
// Check for Empty Inputs
if s is empty or p is empty or length of s < length of p:
  return empty list

// Initialize Result and Counts
p_count = frequency count of each character in p
s_count = frequency count of first len(p)-1 characters in s
initialize result as empty list

// Process Each Window
for i from len(p) - 1 to length of s - 1:
  // Include current character in s_count
  add 1 to s_count[character at index i in s]

  // Compare counts
  if p_count is equal to s_count:
    append i - len(p) + 1 to result

  // Remove character at start of previous window from s_count
  decrease s_count[character at index i - len(p) + 1 in s] by 1

  // If count becomes zero, remove the character from s_count
  if s_count[character at index i - len(p) + 1 in s] is zero:
    remove the character from s_count

// Return result
return result

                                        
This pseudocode provides a clear and detailed approach to solving the challenge while ensuring we explain each step thoroughly. It balances the logic needed to solve the problem with simplicity and clarity.