727. Minimum Window Subsequence

问题描述:

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

解题思路:

仔细读题,注意这里说的是:子序列!!!

子序列意味着每个字符之间的相对顺序不能够改变。

解法参考了zestypanda的解法。

是用动态规划来进行解答。

首先搞清楚dp[j][i]的含义: 对于目标字符串T下标为[0,j]的子串作为子序列出现在给定字符串S[0, i]中的起始位置

初始化dp[0][i]:当S[i] == T[0]时,dp[0][i] = i, else dp[0][i] = -1;

从T的第二个字符开始遍历。

我们用k记录对于T[0, j-1]在当前S[i]之前出现的下标。

当dp[j-1][i] != -1的时候表示到当前i,出现了T[0,j-1]的子序列。将其存入k

若S[i] == T[j], 且 k != -1,表示对于T[0, j]作为子序列出现了。更新dp[j][i].

现在dp中存储的是起始位置。但是我们想要知道的是长度最小的子串。

所以我们遍历dp[n-1][i] (因为要包含T作为子串),找到起始坐标start,子串长度i-start+1最小。

最后需要判断子串是否存在:

若start = -1,则不存在。

此时的空间复杂度为O(mn),可以通过滚动数组的方式,将其优化至O(m)

代码:

class Solution {
public:
    string minWindow(string S, string T) {
        int m = S.size(), n = T.size();
        vector<vector<int>> dp(n, vector<int>(m, -1));
        for(int i = 0; i < m; i++){
            if(S[i] == T[0]) dp[0][i] = i;
        }
        
        for(int j = 1; j < n; j++){
            int k = -1;
            for(int i = 0; i < m; i++){
                if(k != -1 && S[i] == T[j]) dp[j][i] = k;
                if(dp[j-1][i] != -1) k = dp[j-1][i];
            }
        }
        
        int start = -1, len = INT_MAX;
        for(int i = 0; i < m; i++){
            if(dp[n-1][i] != -1 && i - dp[n-1][i]+1 < len){
                start = dp[n-1][i];
                len = i - dp[n-1][i]+1;
            }
        }
        return start == -1 ? "":S.substr(start, len);
    }
};
原文地址:https://www.cnblogs.com/yaoyudadudu/p/9344791.html