Permutation in String medium
Problem Statement
Given two strings s1
and s2
, return true
if s2
contains a permutation of s1
, or false
otherwise.
In other words, return true
if and only if some permutation of s1
is a substring of s2
.
Example 1:
Input: s1 = "ab", s2 = "eidbaooo" Output: true Explanation: s2 contains the permutation "ab" of s1.
Example 2:
Input: s1 = "ab", s2 = "eidboaoo" Output: false
Steps:
- Character Count: Create a map (or array if characters are ASCII) to store the frequency of each character in
s1
. - Sliding Window: Use a sliding window of size equal to the length of
s1
to traverses2
. - Frequency Comparison: For each window in
s2
, count the character frequencies within the window. Compare this frequency count to the frequency count ofs1
. If they match, a permutation is found. - Sliding: Slide the window one position to the right, updating the frequency count accordingly (subtract the outgoing character, add the incoming character).
- Return: Return
true
if a permutation is found; otherwise, returnfalse
after the window has traversed the entires2
.
Explanation:
The core idea is to efficiently check if a sliding window within s2
contains the same character frequencies as s1
. Using a map avoids nested loops for frequency comparison, leading to a linear time solution. The sliding window technique allows for efficient traversal and updating of character counts without recomputing from scratch for each window position.
Code (C++):
#include <iostream>
#include <string>
#include <map>
using namespace std;
bool checkInclusion(string s1, string s2) {
if (s1.length() > s2.length()) return false;
map<char, int> s1_freq;
for (char c : s1) {
s1_freq[c]++;
}
map<char, int> window_freq;
int window_start = 0;
int matched = 0;
for (int window_end = 0; window_end < s2.length(); window_end++) {
char right_char = s2[window_end];
window_freq[right_char]++;
if (s1_freq.count(right_char) && window_freq[right_char] == s1_freq[right_char]) {
matched++;
}
if (window_end - window_start + 1 == s1.length()) {
if (matched == s1_freq.size()) return true;
char left_char = s2[window_start];
window_freq[left_char]--;
if (s1_freq.count(left_char) && window_freq[left_char] < s1_freq[left_char]) {
matched--;
}
window_start++;
}
}
return false;
}
int main() {
string s1 = "ab";
string s2 = "eidbaooo";
cout << checkInclusion(s1, s2) << endl; // Output: true
s1 = "ab";
s2 = "eidboaoo";
cout << checkInclusion(s1, s2) << endl; // Output: false
return 0;
}
Complexity:
- Time Complexity: O(m + n), where n is the length of
s2
and m is the length ofs1
. We iterate throughs2
once. Character frequency counting is done in O(m) and O(n) respectively. - Space Complexity: O(1). The map stores at most 26 characters (for lowercase English letters), so the space used is constant. If the character set is larger, the space complexity becomes O(k), where k is the size of the character set.