Given strings S and T, find the minimum (contiguous) substringW of S, so that T is a subsequence of W.
If there is no such window in S that covers all characters in T, return the empty string "". If there are multiple such minimum-length windows, return the one with the left-most starting index.
Example 1:
Input:
S = "abcdebdde", T = "bde"
Output: "bcde"
Explanation:
"bcde" is the answer because it occurs before "bdde" which has the same length.
"deb" is not a smaller window because the elements of T in the window must occur in order.
Note:
All the strings in the input will only contain lowercase letters.
// Dynamic Programming
// Can use an example to help derive transition state relation
// E.g. S = "dbd", T = "bd"
string minWindow(string S, string T) { // time: O(m * n); space: O(m * n)
int m = S.size(), n = T.size(), start = -1, min_len = INT_MAX;
// Padding one row and one column
// dp[i][j] records the starting index in S s.t. T[0...j - 1] is a subsequence of S[0...i - 1]
vector<vector<int> > dp(m + 1, vector<int> (n + 1, -1));
// Initialize the first col in dp table
for (int i = 0; i <= m; ++i) {
dp[i][0] = i;
}
// DP loop
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
// DP state transition:
// dp[i][j] = dp[i - 1][j - 1] if S[i - 1] == T[j - 1]
// dp[i][j] = dp[i - 1][j] if S[i - 1] != T[j - 1]
dp[i][j] = (S[i - 1] == T[j - 1]) ? dp[i - 1][j - 1] : dp[i - 1][j];
}
// Found possible substring
if (dp[i][n] != -1) {
int len = i - dp[i][n];
if (len < min_len) {
min_len = len;
start = dp[i][n];
}
}
}
return (start != -1) ? S.substr(start, min_len) : "";
}