Permutation in String
Master this topic with zero to advance depth.
Permutation in String
Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise.
Visual Representation
s1 = "ab", s2 = "eidbaooo"
Target Count: {a:1, b:1}
[e, i] d b a o o o Count: {e:1, i:1} (Mismatch)
e [i, d] b a o o o Count: {i:1, d:1} (Mismatch)
e i [d, b] a o o o Count: {d:1, b:1} (Mismatch)
e i d [b, a] o o o Count: {b:1, a:1} (Matches!)Examples
s2 contains one permutation of s1 ("ba").
Level I: Brute Force
Intuition
To check if s2 contains a permutation of s1, we can generate all substrings of s2 that have the same length as s1, and then check if that substring is a permutation of s1 (by sorting both and comparing).
Thought Process
- Iterate through all substrings of
s2with length equal tos1.length(). - For each substring, sort its characters and also sort the characters of
s1. - If the sorted strings match, then a permutation exists.
Detailed Dry Run
| Window in s2 | Sorted Window | Sorted s1 (ab) | Match? |
|---|---|---|---|
| "ei" | "ei" | "ab" | No |
| "id" | "di" | "ab" | No |
| "db" | "bd" | "ab" | No |
| "ba" | "ab" | "ab" | YES |
Level II: Frequency Counter (O(N * 26))
Intuition
Instead of sorting, we can compare character frequency maps. This is still a 'sliding' concept but we re-build or re-check the entire map of size 26 for each window. Since the alphabet size is constant (26), this is technically O(N * 26).
Thought Process
- Count frequencies of characters in
s1. - Iterate through
s2and for every window of sizes1.length(), build a new frequency map. - Compare the window's map with
s1'smap.
Pattern: Frequency Hashing
Level III: Optimal (Sliding Window)
Intuition
Categorization
This is a Fixed Size Window problem because any permutation of s1 must have exactly the same length as s1.
Thought Process
Instead of sorting every substring, we use character frequency counts. A permutation of s1 will have the exact same character frequency count as s1. We maintain a window of size s1.length() in s2 and update the counts as we slide.
Mandatory Variables
left: Marks the start of the window.s1Counts: Frequency map of characters ins1.windowCounts: Frequency map of characters in the currents2window.
Detailed Dry Run
| Window | s2 Fragment | Counts Match? | Action |
|---|---|---|---|
| [0, 1] | "ei" | No | Expand R, Shrink L |
| [1, 2] | "id" | No | Expand R, Shrink L |
| [2, 3] | "db" | No | Expand R, Shrink L |
| [3, 4] | "ba" | YES! | Return True |
⚠️ Common Pitfalls & Tips
Be careful to check the final window after the loop ends, as the last comparison might not happen inside the loop depending on how you structure it.
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.