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

 

posted on 2019-01-08 14:06  周浩炜  阅读(443)  评论(0编辑  收藏  举报

导航