{x}
blog image

Minimum Window Subsequence

Solution Explanation

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:

  1. 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.

  2. 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].

  3. 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.

  4. 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.