115. 不同的子序列-动态规划-困难

问题描述

给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。

一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)

题目数据保证答案符合 32 位带符号整数范围。

示例 1:

输入:S = "rabbbit", T = "rabbit"
输出:3
解释:

如下图所示, 有 3 种可以从 S 中得到 "rabbit" 的方案。
(上箭头符号 ^ 表示选取的字母)

rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^
示例 2:

输入:S = "babgbag", T = "bag"
输出:5
解释:

如下图所示, 有 5 种可以从 S 中得到 "bag" 的方案。
(上箭头符号 ^ 表示选取的字母)

babgbag
^^ ^
babgbag
^^ ^
babgbag
^ ^^
babgbag
^ ^^
babgbag
^^^

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/distinct-subsequences

解答

/*
    dp可解,dfs+回溯会超时
    for(int[] p:arr){
        for(int k:p){
            System.out.print(k);
            System.out.print("	");
        }
        System.out.print("
");
    }

*/
class Solution {
    public int numDistinct(String s, String t) {
        int len_s = s.length();
        int len_t = t.length();
        if(len_s < len_t)return 0;
        if(len_t == 0)return 1;
        int[][] arr = new int[len_s][len_t+1];
        int i,j;
        for(i=0;i<len_s;i++)arr[i][0] = 1;
        if(s.charAt(0) == t.charAt(0))arr[0][1] = 1;
        for(i=1;i<len_s;i++){
            for(j=1;j<len_t+1;j++){
                if(t.charAt(j-1) == s.charAt(i))arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
                else arr[i][j] = arr[i-1][j];
            }
        }
        return arr[len_s-1][len_t];
    }
}
原文地址:https://www.cnblogs.com/xxxxxiaochuan/p/13308692.html