0% completed
Problem Statement
Given a string and a pattern, find out if the string contains any permutation of the pattern.
Permutation is defined as the re-arranging of the characters of the string. For example, “abc” has the following six permutations:
- abc
- acb
- bac
- bca
- cab
- cba
If a string has ‘n’ distinct characters, it will have n! permutations.
Example 1:
Input: str="oidbcaf", pattern="abc"
Output: true
Explanation: The string contains "bca" which is a permutation of the given pattern.
Example 2:
Input: str="odicf", pattern="dc"
Output: false
Explanation: No permutation of the pattern is present in the given string as a substring.
Example 3:
Input: str="bcdxabcdy", pattern="bcdyabcdx"
Output: true
Explanation: Both the string and the pattern are a permutation of each other.
Example 4:
Input: str="aaacb", pattern="abc"
Output: true
Explanation: The string contains "acb" which is a permutation of the given pattern.
Constraints:
- 1 <= str.length, pat.length <= 10<sup>4</sup>
str
andpat
consist of lowercase English letters.
Solution
To solve this problem, we use a sliding window technique combined with a hashmap to keep track of character frequencies. The sliding window allows us to check each substring of the input string efficiently. The hashmap stores the count of each character in the pattern. As we slide the window over the string, we compare the character counts of the current window with those in the hashmap. This approach ensures that we only check substrings that are the same length as the pattern, which makes it very efficient.
The reason this approach is effective is due to its linear time complexity. Instead of generating all possible substrings, we slide a window of fixed size across the string and update our counts dynamically. This reduces the number of comparisons and allows us to quickly determine if a permutation of the pattern exists in the string. It is the most efficient approach as it combines the benefits of the sliding window and hashmap for constant time lookups and updates.
Step-by-step Algorithm
-
Initialization:
- Create a hashmap to store the frequency of each character in the pattern.
- Initialize the
windowStart
pointer andmatchedCount
to 0.
-
Sliding Window Iterations:
- For each character in the string (using
windowEnd
as the end pointer):- Check if the character is in the pattern's frequency map.
- If it is, decrement its count in the map.
- If the character's count in the map reaches 0, increment the matched count.
- If the size of the window exceeds the pattern length:
- Remove the leftmost character (at
windowStart
) from the window. - If the leftmost character is in the pattern's frequency map:
- If its count was 0, decrement the matched count.
- Increment the character's count back in the map.
- Remove the leftmost character (at
- Check if the matched count equals the number of unique characters in the pattern:
- If it does, return
true
.
- If it does, return
- For each character in the string (using
Algorithm Walkthrough
Let's go through the algorithm using the example: str = "aaacb"
, pattern = "abc"
-
Initialization:
- Pattern frequency:
{a: 1, b: 1, c: 1}
- Window Start:
0
- Matched characters count:
0
- Pattern frequency:
-
First Iteration (windowEnd = 0):
- Current window:
a
- Right character:
a
- Updated pattern frequency:
{a: 0, b: 1, c: 1}
matched
count:1
(sincea
frequency is now0
)
- Current window:
-
Second Iteration (windowEnd = 1):
- Current window:
aa
- Right character:
a
- Updated pattern frequency:
{a: -1, b: 1, c: 1}
matched
count:1
(no change sincea
frequency is less than0
)
- Current window:
-
Third Iteration (windowEnd = 2):
- Current window:
aaa
- Right character:
a
- Updated pattern frequency:
{a: -2, b: 1, c: 1}
matched
count:1
(no change sincea
frequency is less than0
)- windowEnd(2) >= pattern.length() - 1. So, increment windowStart and decrement frequency of str[windowStart] in the map.
- Updated pattern frequency:
{a: -1, b: 1, c: 1}
- Current window:
-
Fourth Iteration (windowEnd = 3):
- Current window:
aaac
- Right character:
c
- Updated pattern frequency:
{a: -1, b: 1, c: 0}
matched
count:2
(sincec
frequency is now0
)- windowEnd(2) >= pattern.length() - 1. So, increment windowStart and decrement frequency of str[windowStart] in the map.
- Updated pattern frequency:
{a: 0, b: 1, c: 0}
- Current window:
-
Fifth Iteration (windowEnd = 4):
- Current window:
aaacb
- Right character:
b
- Updated pattern frequency:
{a: 0, b: 0, c: 0}
matched
count:3
(sinceb
frequency is now0
)- Since
matched
count is equal to the size of the pattern (3), returntrue
- Current window:
Code
Here is what our algorithm will look like:
Complexity Analysis
Time Complexity
-
Creating the frequency map: The algorithm first creates a frequency map of the characters in the pattern. This step takes O(M) time, where
M
is the length of the pattern. -
Sliding window traversal: The algorithm uses a sliding window approach to traverse through the string. The outer loop runs for each character in the string, so the loop runs O(N) times, where
N
is the length of the input string. -
Character frequency updates: For each character in the window, the algorithm performs constant-time operations like updating the frequency in the
charFrequencyMap
and adjusting thematched
count. These operations take O(1) time on average, as hash map operations likeput()
andget()
are constant on average. -
Therefore, the total time complexity is O(N + M), where
N
is the length of the input string andM
is the length of the pattern.
Overall time complexity: O(N + M).
Space Complexity
-
HashMap space: The algorithm uses a hash map,
charFrequencyMap
, to store the frequency of characters in the pattern. This requires O(M) space, whereM
is the number of unique characters in the pattern. -
Additional variables: The algorithm uses a few extra variables (
windowStart
,windowEnd
,matched
), all of which require constant space, O(1). No additional data structures are used that depend on the input size.
Overall space complexity: O(M), where M
is the number of unique characters in the pattern.
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible