727. Minimum Window Subsequence

动态规划里面最难的地方是DP状态的定义。
但是DP的思考过程最好是从递归出发。
如果我想知道S里面包含T做为subsequence的最小长度,
那我需要知道以S的每个点做为结尾的包含T subsequence的最小长度。
如果S的最后一个字母不等于T的最后一个字母,那么我们match n-1 和m;
如果S的最后一个字母等于T的最后一个字母,那么我们match n- 1和 m-1。

当然DP的定义可以有多种定义方式。
这里DP状态的定义dp[i][j]是以一定以第i个字母结尾的能match前j个字符的最小长度。

        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) { 
                dp[i][j] = -1; //初始化为 -1;
                if (S.charAt(i - 1) == T.charAt(j - 1)) {
                   if (dp[i - 1][j - 1] != -1) dp[i][j] = 1 + dp[i - 1][j - 1]; //如果前面能match上才更新
                } else {
                    if (dp[ i - 1][j] != -1) dp[i][j] = 1 +  dp[i - 1][j];//如果前面能match上才更新
                }
            }
        }
    public String minWindow(String S, String T) {
        int N = S.length(); int M = T.length();
        int[][] dp = new int[N + 1][M + 1];
        for (int j = 1; j <= M; j++) dp[0][j] = -1;
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= M; j++) { 
                dp[i][j] = -1;
                if (S.charAt(i - 1) == T.charAt(j - 1)) {
                    if (dp[i - 1][j - 1] != -1) {
                        dp[i][j] = 1 + dp[i - 1][j - 1];
                    } 
                } else {
                    if (dp[ i - 1][j] != -1) dp[i][j] = 1 +  dp[i - 1][j];
                }
            }
        }
        int best = N + 1;
        String result = "";
        for (int right = M - 1; right <= N; right++) {
            if (dp[right][M] != -1 && dp[right][M]  < best) {
                best = dp[right][M];
                result = S.substring(right - best , right);
            }
        }
        return result;
    }
}

你可能感兴趣的:(727. Minimum Window Subsequence)