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 };