#567 Permutation in String
frequently reported atWalmartMicrosoftAmazonBloombergGoogleAdobe
the problem
In plain words
Return true if some permutation of s1 appears as a substring of s2 — that is, if s2 contains an anagram of s1.
in s1 = "ab", s2 = "eidbaooo"
out true
"ba" is in s2.
in s1 = "ab", s2 = "eidboaoo"
out false
- 1 ≤ s1.length, s2.length ≤ 10⁴
- Lowercase English letters
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternSliding window (fixed size)Frequency counting
A permutation has the same letter counts. Slide a window of size |s1| over s2 and compare counts — the window changes by one letter in, one letter out.
solutions
From brute force to optimal
Two strings are permutations iff their sorted forms are equal.
- Sort s1.
- For each window of size m in s2, sort it and compare.
n − m + 1 windows, each sorted in m log m (m = |s1|, n = |s2|).
A copy of each window.
class Solution { public boolean checkInclusion(String s1, String s2) { char[] target = s1.toCharArray(); Arrays.sort(target); for (int start = 0; start + s1.length() <= s2.length(); start++) { char[] window = s2.substring(start, start + s1.length()).toCharArray(); Arrays.sort(window); // m log m per window if (Arrays.equals(window, target)) return true; } return false; }}Keep have[26] for the window; after each slide compare with need[26].
- need = counts of s1.
- Slide over s2: add the new letter, remove the letter m positions back.
- If Arrays.equals(need, have) → true.
Each slide is O(1) plus a 26-element comparison.
Two arrays of 26.
class Solution { public boolean checkInclusion(String s1, String s2) { if (s1.length() > s2.length()) return false; int[] need = new int[26], have = new int[26]; for (char c : s1.toCharArray()) need[c - 'a']++; int m = s1.length(); for (int right = 0; right < s2.length(); right++) { have[s2.charAt(right) - 'a']++; if (right >= m) have[s2.charAt(right - m) - 'a']--; if (Arrays.equals(need, have)) return true; // 26 comparisons } return false; }}Track how many letters are "off". Only the two letters that change can flip that number.
- diff[c] = need − have; bad = letters with diff ≠ 0.
- On each update, check whether diff[c] crossed 0 and adjust bad.
- If the window is full and bad == 0 → true.
Truly O(1) per slide — no 26-element comparison.
One array of 26 and a counter.
class Solution { public boolean checkInclusion(String s1, String s2) { int m = s1.length(); if (m > s2.length()) return false; int[] diff = new int[26]; // need minus have, per letter for (char c : s1.toCharArray()) diff[c - 'a']++; int bad = 0; // letters whose count is still off for (int d : diff) if (d != 0) bad++; for (int right = 0; right < s2.length(); right++) { int in = s2.charAt(right) - 'a'; if (diff[in] == 0) bad++; // was balanced, now off by one if (--diff[in] == 0) bad--; if (right >= m) { int out = s2.charAt(right - m) - 'a'; if (diff[out] == 0) bad++; if (++diff[out] == 0) bad--; } if (right >= m - 1 && bad == 0) return true; } return false; }}Dry run
in the room
How to say it in the interview
talk track
- Translate the problem: "permutation of s1 as a substring" = "a window of size |s1| with the same counts".
- Give the Arrays.equals version first — it is already O(n). Offer the counter as an optimisation.
traps
- Forgetting the early return when s1 is longer than s2.
- Using a variable window — the size is fixed at |s1|.
what they ask next
Follow-ups
Find All Anagrams in a String (LC 438)?
The same window, but record every start where bad == 0 and keep sliding instead of returning — it's the next problem in this chapter.
before you submit
Edge cases to test
- s1 longer than s2 → false straight away.
- Repeated letters: "aab" needs two a's, not just "some a".
- The match can be the very last |s1| letters of s2.
- s1 equal to s2 → true.
practise next
Similar problems
- #438Find All Anagrams in a StringMediumin Sliding Window
- #242Valid AnagramEasyin Arrays & Strings
- #76Minimum Window SubstringHardin Sliding Window