Leetcode 727. Minimum Window Subsequence
Problem:
Given strings S
and T
, find the minimum (contiguous) substring W
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.
- The length of
S
will be in the range[1, 20000]
. - The length of
T
will be in the range[1, 100]
.
Solution:
这道题拿到手的第一想法应该是动态规划,用dp[i][j]代表前i个T中的字符和前j个S中的字符在S中满足条件的最大开始位置,说起来很绕,以Example 1为例,首先初始化第一行,当碰T[i]等于S[j]时,将j赋值给dp[i][j],否则dp[i][j]等于dp[i][j-1]。对于其余的行,如果T[i]等于S[j],那么dp[i][j]等于dp[i-1][j],为什么要这么做?那是因为我知道了前i-1个T字符串和前j个S字符串在S中的最大开始位置,而T[i]和S[j]又是相等的,那么即使多了一个T中的i位置的字符也不会影响结果,所以dp[i][j]=dp[i-1][j],如果T[i]和S[j]不等,那么dp[i][j]等于dp[i][j-1]。但这里有个陷阱,看"cnhczmccqouqadqtmjjzl"和"mm"这个例子,如果简单的按照这个逻辑,T的第二个m会和S的第一个m重复使用,因此需要多一布判断T[i]和T[i-1]是否相同,如果相同的话dp[i][j]就等于dp[i-1][j-1].
a | b | c | d | e | b | d | d | e | |
b | -1 | 1 | 1 | 1 | 1 | 5 | 5 | 5 | 5 |
d | -1 | -1 | -1 | 1 | 1 | 1 | 5 | 5 | 5 |
e | -1 | -1 | -1 | -1 | 1 | 1 | 1 | 1 | 5 |
Code:
1 class Solution { 2 public: 3 string minWindow(string S, string T) { 4 int m = S.size(); 5 int n = T.size(); 6 vector<vector<int>> dp(n,vector<int>(m,-1)); 7 for(int j = 0;j != m;++j){ 8 if(T[0] == S[j]) 9 dp[0][j] = j; 10 else{ 11 if(j != 0) 12 dp[0][j] = dp[0][j-1]; 13 } 14 } 15 for(int i = 1;i != n;++i){ 16 for(int j = 0;j != m;++j){ 17 if(S[j] == T[i]){ 18 if(T[i] == T[i-1]){ 19 if(j != 0) 20 dp[i][j] = dp[i-1][j-1]; 21 } 22 else 23 dp[i][j] = dp[i-1][j]; 24 } 25 else{ 26 if(j != 0) 27 dp[i][j] = dp[i][j-1]; 28 } 29 } 30 } 31 string result = ""; 32 int minlength = INT_MAX; 33 for(int j = 0;j != m;++j){ 34 if(dp[n-1][j] != -1 && j-dp[n-1][j]+1 < minlength){ 35 minlength = j-dp[n-1][j]+1; 36 result = S.substr(dp[n-1][j],minlength); 37 } 38 } 39 return result; 40 } 41 };