This problem asks to find the minimum window substring of s1
that contains s2
as a subsequence. The solution uses dynamic programming to efficiently find this window.
Approach:
Dynamic Programming Table: A 2D DP table f
of size (m+1) x (n+1) is created, where m
is the length of s1
and n
is the length of s2
. f[i][j]
stores the starting index of the minimum window in s1[0:i]
that contains s2[0:j]
as a subsequence. If no such window exists, f[i][j]
will be 0.
DP Relation: The DP relation is defined as follows:
If s1[i-1] == s2[j-1]
: This means we've found a character matching the current character in s2
. If it's the first character of s2
(j == 1), the window starts at i
. Otherwise, the window starts at the index found in f[i-1][j-1]
.
If s1[i-1] != s2[j-1]
: The current character in s1
doesn't match the current character in s2
. In this case, we inherit the best window from the previous row: f[i][j] = f[i-1][j]
.
Finding the Minimum Window: After filling the DP table, we iterate through the last column (f[:, n]
). If f[i][n]
is non-zero, it indicates that a window ending at index i
contains s2
as a subsequence. We track the minimum window length and its starting index.
Result: Finally, the function returns the minimum window substring or an empty string if no such window exists.
Time Complexity: O(m*n), where 'm' and 'n' are the lengths of strings s1 and s2 respectively. This is due to the nested loops used to fill the DP table.
Space Complexity: O(m*n), due to the DP table.
Code Explanation (Python):
class Solution:
def minWindow(self, s1: str, s2: str) -> str:
m, n = len(s1), len(s2)
f = [[0] * (n + 1) for _ in range(m + 1)] # Initialize DP table
for i, a in enumerate(s1, 1):
for j, b in enumerate(s2, 1):
if a == b:
f[i][j] = i if j == 1 else f[i - 1][j - 1] #DP Relation
else:
f[i][j] = f[i - 1][j]
p, k = 0, m + 1 # Initialize min window length and start index
for i, a in enumerate(s1, 1):
if a == s2[n - 1] and f[i][n]: #check for the last character of s2
j = f[i][n] - 1
if i - j < k: # Update min window if a smaller one is found
k = i - j
p = j
return "" if k > m else s1[p : p + k] # Return the result
The code in other languages (Java, C++, Go, TypeScript) follows the same logic and DP relation, just with syntax variations specific to each language. They all achieve the same time and space complexity.