Find All Anagrams in a String - Complete Solution Guide
Find All Anagrams in a String is LeetCode problem 438, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
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". Th
Detailed Explanation
The problem requires you to find all starting indices of substrings within a given string `s` that are anagrams of another given string `p`. An anagram is a rearrangement of the letters in a word or phrase to produce a new word or phrase, using all the original letters exactly once. The input consists of two strings, `s` and `p`, and the output is a list of integer indices indicating the starting positions of the anagrams of `p` found in `s`. The length of both strings is between 1 and 3 * 10^4, and they contain only lowercase English letters.
Solution Approach
The provided solution employs a sliding window technique coupled with frequency counting to solve this problem. It initializes frequency maps for both the pattern `p` and the first window (substring of length `p`) in the string `s`. Then, it slides the window one character at a time across `s`, updating the frequency map for the current window by adding the new character and removing the leaving character. In each step, it checks if the current window's frequency map is identical to that of `p`. If they match, it means an anagram is found, and the starting index of the window is added to the result.
Step-by-Step Algorithm
- Step 1: Check if the length of `s` is less than the length of `p`. If it is, return an empty list since `p` cannot be an anagram of any substring of `s`.
- Step 2: Initialize two frequency arrays (or hash maps) `p_count` and `s_count` of size 26 (one for each lowercase English letter).
- Step 3: Populate `p_count` with the frequencies of characters in `p`.
- Step 4: Populate `s_count` with the frequencies of the first `len(p)` characters in `s`. This represents the initial sliding window.
- Step 5: Compare `p_count` and `s_count`. If they are equal (meaning they represent the same character frequencies), add 0 (the starting index of the first window) to the result list.
- Step 6: Iterate from index `len(p)` to the end of `s`. In each iteration:
- Step 7: - Update `s_count` by incrementing the frequency of the character entering the window (the current character in `s`) and decrementing the frequency of the character leaving the window (the character at index `i - len(p)`).
- Step 8: - Compare `p_count` and `s_count`. If they are equal, add `i - len(p) + 1` (the starting index of the current window) to the result list.
- Step 9: Return the result list.
Key Insights
- Insight 1: Using a sliding window approach allows us to efficiently scan through the string `s` without recomputing character frequencies for each substring.
- Insight 2: Representing character frequencies using an array of fixed size (26 for lowercase English letters) enables constant-time comparisons to check if two strings are anagrams.
- Insight 3: Pre-calculating the character frequency map for the pattern `p` allows us to compare it efficiently with each window in `s`.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Hash Table, String, Sliding Window.
Companies
Asked at: Bolt, Databricks, Intuit, Revolut, Snowflake, Splunk, Turing, Yandex.