剑指 Offer II 097. 子序列的数目(115. 不同的子序列)

题目:

思路:

【1】动态规划的方式

代码展示:

动态规划的方式(一维数组):

//利用两个一维数组轮流交替达到二维数组的效果
//时间4 ms击败86.35%
//内存42.6 MB击败80.32%
class Solution {
    public int numDistinct(String s, String t) {
        if(t.length() > s.length()) return 0; // s长度小于t时间直接返回0
        int ns = s.length(), nt = t.length();
        int[] pre = new int[nt + 1], cur = new int[nt + 1];
        char[] chss = s.toCharArray(), chst = t.toCharArray();
        pre[0] = 1;
        cur[0] = 1; // 当t为空串时,此行是必须的
        for(int i = 1; i <= ns; i++){
            for(int j = 1; j <= nt; j++){
                if(chss[i - 1] == chst[j - 1]) cur[j] = pre[j - 1] + pre[j];
                else cur[j] = pre[j];
            }
            pre = Arrays.copyOf(cur, nt + 1); // for(int k = 0; k <= nt; k++) pre[k] = cur[k];
        }
        return cur[nt];
    }
}

//只是用一维数组的变量方式
//时间2 ms击败99.51%
//内存39.6 MB击败87.58%
class Solution {
    public int numDistinct(String s, String t) {
        if(s.length() < t.length()) return 0; // s长度小于t时,s中不会出现t
        int ns = s.length(), nt = t.length();
        char[] chss = s.toCharArray(), chst = t.toCharArray();
        int[] dp = new int[nt + 1];
        dp[0] = 1;
        int pre = dp[0];
        for(int i = 1; i <= ns; i++){
            for(int j = 1; j <= nt; j++){
                int nextPre = dp[j]; // 相当于二维矩阵中待更新的dp[i][j]的dp[i - 1][j - 1]
                if(chss[i - 1] == chst[j - 1] ) dp[j] += pre;
                pre = nextPre;
            }
            pre = 1; // 每完成一行要重置该值为1
        }
        return dp[nt];
    }
}

 

 

 

动态规划的方式(二维数组):

//二维数组的辅助变量(正序)
//时间4 ms击败86.35%
//内存43.6 MB击败80.7%
class Solution {
    public int numDistinct(String s, String t) {
        if(s.length() < t.length()) return 0; // s长度小于t时,s中不会出现t
        int ns = s.length(), nt = t.length();
        char[] chss = s.toCharArray(), chst = t.toCharArray();
        int[][] dp = new int[ns + 1][nt + 1];
        for(int i = 0; i <= ns; i++) dp[i][0] = 1; 
        for(int i = 1; i <= ns; i++){
            for(int j = 1; j <= nt; j++){
                dp[i][j] = dp[i - 1][j] + (chss[i - 1] == chst[j - 1] ? dp[i - 1][j - 1] : 0);
            }
        }
        return dp[ns][nt];
    }
}

//二维数组的辅助变量(逆序)
//时间10 ms击败81.42%
//内存45.7 MB击败92.78%
class Solution {
    public int numDistinct(String s, String t) {
        int m = s.length(), n = t.length();
        if (m < n) {
            return 0;
        }
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 0; i <= m; i++) {
            dp[i][n] = 1;
        }
        for (int i = m - 1; i >= 0; i--) {
            char sChar = s.charAt(i);
            for (int j = n - 1; j >= 0; j--) {
                char tChar = t.charAt(j);
                if (sChar == tChar) {
                    dp[i][j] = dp[i + 1][j + 1] + dp[i + 1][j];
                } else {
                    dp[i][j] = dp[i + 1][j];
                }
            }
        }
        return dp[0][0];
    }
}

 

posted @ 2023-05-08 13:36  忧愁的chafry  阅读(19)  评论(0)    收藏  举报