Distinct Subsequences——Leetcode
Given a string S and a string T, count the number of distinct subsequences of T in S.
A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE"
is a subsequence of "ABCDE"
while "AEC"
is not).
Here is an example:
S = "rabbbit"
, T = "rabbit"
Return 3
.
题目大意:给两个字符串S,T,问从S中可以有多少不同的子序列是T,子序列只能删源字符串元素。
解题思路:
动态规划,这个题要复杂一些,首先来看怎么定义状态是最关键的,题目要求是从S到T,如果S中只有一个合法的T,结果应该是1。
dp[i][j]表示字符串S[0...i]到T[0...j]具有多少种变化形式,首先可以确定的是,dp[i][0]=1,意思表示从S到空字符串变换形式只有一种,就是删除S中所有的字符串。
除此之外,如果S[i]!=T[j],dp[i][j]=dp[i-1][j],意思是如果当前字符不等,那么就只能抛弃当前这个字符。
如果S[i]==T[j],dp[i][j]=dp[i-1][j-1]+dp[i-1][j],意思是如果当前字符不等,那么可以抛弃当前这个字符,也可以要这个字符,dp[i-1][j-1]就表示从字符串S[0...i-1]到T[0...j-1]的变化次数,dp[i-1][j]就表示从字符串S[0...i-1]到T[0...j]的变化次数,这两个加起来就表示要和不要这个字符一共有多少种变化形式。
public int numDistinct(String s, String t) { if(s==null||t==null){ return 0; } int[][] dp = new int[s.length()+1][t.length()+1]; for(int i=0;i<=s.length();i++)dp[i][0]=1; for(int i=1;i<=s.length();i++){ for(int j=1;j<=t.length();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]; } } } return dp[s.length()][t.length()]; }