42. Permutation in String
Problem Statement
Given two strings s1
and s2
, return true
if s2
contains one of the permutations of s1
, or false
otherwise.
In other words, return true
if one of s1
's permutations is the substring of s2
.
Example 1:
Input: s1 = "ab", s2 = "eidbaooo" Output: true Explanation: s2 contains one permutation of s1 ("ba").
Example 2:
Input: s1 = "ab", s2 = "eidboaoo" Output: false
Solution
from collections import Counter
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
len1, len2 = len(s1), len(s2)
if len1 > len2:
return False
# Count character frequencies for s1
s1_counts = Counter(s1)
# Count character frequencies for the initial window in s2
window_counts = Counter(s2[:len1])
# Check if the initial window is a permutation
if s1_counts == window_counts:
return True
# Slide the window across s2
for i in range(len1, len2):
# Add the new character entering the window
window_counts[s2[i]] += 1
# Remove the character leaving the window
window_counts[s2[i - len1]] -= 1
# If a character count becomes zero, remove it from the counter
# to ensure accurate comparison with s1_counts
if window_counts[s2[i - len1]] == 0:
del window_counts[s2[i - len1]]
# Check if the current window is a permutation
if s1_counts == window_counts:
return True
return False
Explanation
This problem can be solved using a sliding window approach combined with frequency maps.
Core Idea: A string s2
contains a permutation of s1
if there is a substring in s2
that has the exact same character counts as s1
.
-
Initial Setup:
- Check if
len(s1)
is greater thanlen(s2)
. If so, a permutation ofs1
cannot exist ins2
, so returnFalse
. - Create a frequency map (
s1_counts
) fors1
. - Create a frequency map (
window_counts
) for the initial window ins2
(of lengthlen(s1)
). - Compare
s1_counts
andwindow_counts
. If they are equal, we found a permutation.
- Check if
-
Sliding Window:
- Iterate from
len1
tolen2 - 1
(the end ofs2
). In each iteration, we simulate sliding the window one position to the right. - Add Character: Add the new character
s2[i]
(entering the window) towindow_counts
. - Remove Character: Remove the character
s2[i - len1]
(leaving the window) fromwindow_counts
. If its count becomes 0, delete it from the map to ensure accurate comparison. - Compare: After updating
window_counts
, compare it withs1_counts
. If they are equal, returnTrue
.
- Iterate from
-
Return False: If the loop completes without finding a matching window, return
False
.
Time and Space Complexity:
- Time Complexity: O(L1 + L2), where L1 is
len(s1)
and L2 islen(s2)
. We iterate throughs1
once to build its frequency map, and then iterate throughs2
once with the sliding window. Dictionary operations (add, remove, compare) take O(alphabet_size) time, which is constant (26 for lowercase English letters). - Space Complexity: O(alphabet_size) for storing the frequency maps.