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

class Solution {
    public String minWindow(String S, String T) {
        int m = S.length(), n = T.length();
        if (m < n) return "";
        int[][] dp = new int[m][n];
        //find the subsequence start index
        for (int i = 0; i < m; i++) {
            if (S.charAt(i) == T.charAt(0)) dp[i][0] = i;
            else {
                if (i == 0) dp[i][0] = -1;
                else dp[i][0] = dp[i-1][0];
            }
        }
        
        //initialize all dp[0][j] (j != 0) to -1
        for (int j = 1; j < n; j++) {
            dp[0][j] = -1;
            for (int i = 1; i < m; i++) {
                if (S.charAt(i) == T.charAt(j)) {
                    dp[i][j] = dp[i-1][j-1];
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        
        //initialize len to an impossible large value
        int start = 0, len = m+1;
        for (int i = n-1; i < m; i++) {
            if (dp[i][n-1] != -1) {
                if (i-dp[i][n-1]+1 < len) {
                    len = i-dp[i][n-1]+1;
                    start = dp[i][n-1];
                }
            }
        }
        
        if (len == m+1) return "";
        return S.substring(start, start+len);
    }
}

linspiration
161 声望53 粉丝