Two approaches to LeetCode Permutation in String β sort every window O(nΒ·k log k) and optimal fixed-size sliding window with frequency match O(n). Java and Python solutions.
LeetCode Β· #567
Permutation in String Solution
Given two strings s1 and s2, return true if s2 contains a permutation of s1.
Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise. In other words, return true if one of s1's permutations is a substring of s2.
Example 1
Input: s1 = "ab", s2 = "eidbaooo"Output:true// s2 contains "ba" which is a permutation of "ab"
Example 2
Input: s1 = "ab", s2 = "eidboaoo"Output:false// No substring of length 2 in s2 has the same character frequencies as "ab"
Constraints
β’ 1 β€ s1.length, s2.length β€ 10β΄β’ s1 and s2 consist of lowercase English letters
02
Section Two Β· Approach 1
Brute Force β Sort Every Window
Slide a window of size len(s1) over s2. For each window, sort the characters and compare with sorted s1. If they match, it's a permutation.
Problem: Sorting each window costs O(k log k) where k = len(s1), repeated ~n times β O(nΒ·k log k). A frequency array comparison replaces sorting with O(26) = O(1) per slide.
Java β Sort & Compare
import java.util.Arrays;
classSolution {
publicbooleancheckInclusion(String s1, String s2) {
char[] target = s1.toCharArray();
Arrays.sort(target);
for (int i = 0; i <= s2.length() - s1.length(); i++) {
char[] window = s2.substring(i, i + s1.length()).toCharArray();
Arrays.sort(window);
if (Arrays.equals(target, window)) returntrue;
}
returnfalse;
}
}
Python β Sort & Compare
classSolution:
defcheckInclusion(self, s1: str, s2: str) -> bool:
target = sorted(s1)
k = len(s1)
for i in range(len(s2) - k + 1):
if sorted(s2[i:i + k]) == target:
returnTruereturnFalse
Metric
Value
Time
O(n Β· k log k)
Space
O(k)
03
Section Three Β· Approach 2
Fixed-Size Sliding Window β O(n)
Build a frequency array for s1. Slide a window of size len(s1) across s2, maintaining a window frequency array. When the window slides, add the new right character and remove the old left character. If both frequency arrays match β permutation found.
π‘ Mental model: You have a cookie cutter (s1's frequency signature) and a long strip of dough (s2). You slide the cutter one position at a time. At each position, you check if the dough under the cutter has the exact same ingredient distribution. Instead of re-measuring from scratch, you update the counts: add the new ingredient entering on the right, remove the one leaving on the left.
Algorithm
Step 1: Build s1Count[26] from s1.
Step 2: Build s2Count[26] from the first len(s1) characters of s2. Compare.
O(1) per slide; tracks matching slots incrementally
07
Section Seven Β· Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
s1 longer than s2
s1="abc", s2="ab"
Impossible β return false immediately.
Exact match
s1="abc", s2="abc"
The entire s2 is a permutation of s1 β true.
Single char
s1="a", s2="a"
Trivial match.
No overlap
s1="ab", s2="ccc"
None of s1's characters exist in s2 β false.
Permutation at end
s1="ab", s2="xxxba"
Match at the last window position. Must check the final window.
β Common Mistake: Forgetting to check matches == 26 after the loop ends. The last window position is processed inside the loop body, but the final check happens only when returning. Always return matches == 26 at the end to catch a match at the last position.