0% completed
Problem Statement
Given a string and a pattern, find the smallest substring in the given string which has all the character occurrences of the given pattern.
Example 1:
Input: String="aabdec", Pattern="abc"
Output: "abdec"
Explanation: The smallest substring having all characters of the pattern is "abdec"
Example 2:
Input: String="aabdec", Pattern="abac"
Output: "aabdec"
Explanation: The smallest substring having all characters occurrences of the pattern is "aabdec"
Example 3:
Input: String="abdbca", Pattern="abc"
Output: "bca"
Explanation: The smallest substring having all characters of the pattern is "bca".
Example 4:
Input: String="adcad", Pattern="abc"
Output: ""
Explanation: No substring in the given string has all characters of the pattern
Constraints:
- m == String.length
- n == Pattern.length
- 1 <= m, n <= 10<sup>5</sup>
String
andPattern
consist of uppercase and lowercase English letters.
Solution
To solve this problem, we use the sliding window technique. This approach helps us dynamically adjust the range of the substring we're considering. We start with two pointers, one at the beginning and another that expands to include new characters. As we move the right pointer to include characters, we check if the current window contains all the characters from pattern
in the required frequency. Once it does, we try to shrink the window from the left to find the smallest possible window. This method is efficient because it avoids redundant calculations by reusing information from the previous state.
This approach is effective because it ensures that each character in s
is processed at most twice (once by each pointer), resulting in a linear time complexity relative to the length of s
. The space complexity is manageable, as we only store the frequency of characters in a hash map. This guarantees that the solution is both time and space efficient.
Step-by-step Algorithm
-
Initialize Variables:
- Create a hash map to store the frequency of characters in
pattern
. - Initialize variables:
windowStart
to track the start of the window,minLength
to track the minimum window size,matched
to count matched characters, andsubStrStart
to remember the start index of the smallest window.
- Create a hash map to store the frequency of characters in
-
Expand the Window:
- Iterate through
s
withwindowEnd
. - For each character at
windowEnd
, check if it is in the hash map. If yes, decrement its frequency in the map. - If the character's frequency in the map is zero or more, increment the
matched
count.
- Iterate through
-
Shrink the Window:
- While
matched
equals the length ofpattern
, it means the current window contains all characters ofpattern
. - Update the
minLength
andsubStrStart
if the current window size is smaller than the previous smallest window. - Move the
windowStart
to the right to shrink the window. If the character atwindowStart
is in the hash map, increase its frequency in the map. If its frequency becomes zero, decrement thematched
count.
- While
-
Return Result:
- After processing all characters, if
minLength
is greater than the length ofs
, return an empty string. Otherwise, return the substring starting atsubStrStart
with the length ofminLength
.
- After processing all characters, if
Algorithm Walkthrough
Example:
s = "aabdec"
t = "abc"
-
Initialize:
charFrequencyMap
: {a: 1, b: 1, c: 1}windowStart = 0
,matched = 0
,minLength = 7
,subStrStart = 0
-
Iteration:
windowEnd = 0
:rightChar = 'a'
charFrequencyMap
: {a: 0, b: 1, c: 1},matched = 1
windowEnd = 1
:rightChar = 'a'
charFrequencyMap
: {a: -1, b: 1, c: 1},matched = 1
windowEnd = 2
:rightChar = 'b'
charFrequencyMap
: {a: -1, b: 0, c: 1},matched = 2
windowEnd = 3
:rightChar = 'd'
- No change in
charFrequencyMap
ormatched
- No change in
windowEnd = 4
:rightChar = 'e'
- No change in
charFrequencyMap
ormatched
- No change in
windowEnd = 5
:rightChar = 'c'
charFrequencyMap
: {a: -1, b: 0, c: 0},matched = 3
matched == t.length()
: UpdateminLength = 6
,subStrStart = 0
windowStart = 1
:leftChar = 'a'
charFrequencyMap
: {a: 0, b: 0, c: 0},matched = 3
,minLength = 5
,subStrStart = 1
windowStart = 2
:leftChar = 'a'
charFrequencyMap
: {a: 1, b: 0, c: 0},matched = 2
-
Result:
minLength = 5
,subStrStart = 1
- Return
s.substring(1, 1 + 5)
=> "abdec"
Code
Here is what our algorithm will look:
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 such as 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.
Overall time complexity: The total time complexity is O(N + M), where N$
is the length of the string and M$
is the length of the pattern.
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 such as
windowStart
,windowEnd
,matched
,minLength
, andsubStrStart
, all of which require constant space, O(1).
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