LeetCode—115. Distinct Subsequences

LeetCode—115. Distinct Subsequences

题目

https://leetcode.com/problems/distinct-subsequences/description/
子序列问题。给出两个字符串s和t,找出s中有多少子序列等于t。
在这里插入图片描述

思路及解法

首先区别子串和子序列。LeetCode—53. Maximum Subarray这道题是子串的问题,我们曾经提到过。子串是在原字符串中每个字符必须是相连的,而子序列则要求更宽泛一些,只要原顺序不变就行了,不需要每个字符是相邻的。
这也是动态规划的问题。因为是两个字符串,所以应该可以能想到是一个二维的dp数组。我们用dp[i][j]表示,s的前i个字符形成的子串,可以表示为t的前j个字符形成的子串的方式数。
考虑递归关系,新来一个字符s[i],如果s[i]!=t[j],那么不能形成新的子串表示方法,所以dp[i][j]=dp[i-1][j];
如果s[i]==t[j],这种情况的表示方式由两部分组成,第一部分dp[i-1][j],s[i]不加入时的表示方式;第二部分,dp[i][j]=dp[i-1][j-1],s[i]加入时的表示方式,我们这样想,既然s[i]和t[j]相等,那么将两者同时拿出去,仍然是一种属于s[i]的子表示方式,并且和上一种方式互斥,所以两者相加就是解果,dp[i][j]=dp[i-1][j]+dp[i-1][j-1]
在这里插入图片描述

代码

class Solution {
    public int numDistinct(String s, String t) {
        int s_len = s.length(), t_len = t.length();
        int[][] dp = new int[s_len+1][t_len+1];
        dp[0][0] = 1;
        for(int i=1; i<=s_len; i++){
            dp[i][0] = 1;
        }
        for(int j=1; j<=t_len; j++){
            dp[0][j] = 0;
        }
        for(int i=1; i<=s_len; i++){
            for(int j=1; j<=t_len; j++){
                
                // if(s.charAt(i-1) == t.charAt(j-1)){
                //     dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
                // }else{
                //     dp[i][j] = dp[i-1][j];
                // }
                dp[i][j] = dp[i-1][j];
                if(s.charAt(i-1) == t.charAt(j-1)){
                    dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
                }
            }
        }
        return dp[s_len][t_len];
    }
}

猜你喜欢

转载自blog.csdn.net/pnnngchg/article/details/82931583