给定两个字符串S和T,返回S子序列等于T的不同子序列个数有多少个?
字符串的子序列是由原来的字符串删除一些字符(也可以不删除)在不改变相对位置的情况下的剩余字符(例如,"ACE"is a subsequence of"ABCDE"但是"AEC"不是)
例如:
例如:
S="nowcccoder", T = "nowccoder"
返回3
"nowcccoder","nowccoder"
3
//运行时间过长 import java.util.ArrayList; public class Solution { int num=0; int flag=1; public int numDistinct(String S, String T) { if(S==null||T==null) return 0; int len1=S.length(); int len2=T.length(); if(len2>len1){ return 0; } ArrayList<Character> list=new ArrayList<Character>(); backtracking(S,T,len2,0,list); return num; } public void backtracking(String S,String T,int k,int start,ArrayList<Character> list){ if(k<0){ return; } else if(k==0){ for(int i=0;i<T.length();i++){ if(list.get(i)!=T.charAt(i)){ flag=0; break; } } if(flag==1){ num++; } flag=1; return; } else{ for(int i=start;i<S.length();i++){ list.add(S.charAt(i)); backtracking(S,T,k-1,i+1,list); list.remove(list.size()-1); } } } }
class Solution { /** * DP: 假设dp[i][j]是S中前i个字符构成的子串和T中前j个字符构成 * 的子串匹配得到的子序列数量,求dp[S.length()][T.length()] * 1. 初始条件dp[i][0],S的前i的任意子串与空串有一个匹配的序列,dp[i][0]=1 * 初始条件dp[0][j](j>0),S的空串与任意非空串无匹配的子序列,dp[0][j]=0 * 2. 转义条件,求dp[i][j]的值有两种情况: * 1)S[i-1]!=T[j-1], dp[i][j]=dp[i-1][j] S的i-1位置与T的j-1不匹配 * 那么符合的匹配序列数量和S的前i-1个字符的子串一样 * 2) S[i]==T[j-1], dp[i][j]=dp[i-1][j]+dp[i-1][j-1] S的i-1与T的j-1匹配 * 那么符合匹配的序列数等于前i-1就符合与T前j匹配的,加上S前i-1子串和 * T的前j-1子串匹配的。 */ public int numDistinct(String s, String t) { int[][] num = new int[s.length()+1][t.length()+1]; for(int i=0; i<=s.length(); i++){ num[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)){ num[i][j] = num[i-1][j] + num[i-1][j-1]; } else { num[i][j] = num[i-1][j]; } } } return num[s.length()][t.length()]; } }
public class Solution { public int numDistinct(String S, String T) { int length=T.length()+1; int width=S.length()+1; int[][]num=new int[length][width]; for(int i=0;i<length;i++) num[i][0]=0; for(int n=0;n<width;n++) num[0][n]=1; for(int j=1;j<length;j++) for(int m=1;m<width;m++) { if(S.charAt(m-1)==T.charAt(j-1)) {num[j][m]=num[j][m-1]+num[j-1][m-1]; } else num[j][m]=num[j][m-1]; } return num[length-1][width-1]; } }
public class Solution { public int numDistinct(String S, String T) { int[][] dp = new int[S.length()+1][T.length()+1]; dp[0][0] = 1; for(int i=1; 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(i < j) dp[i][j] = 0; else { if(S.charAt(i-1) == T.charAt(j-1)) dp[i][j] += dp[i-1][j-1]; dp[i][j] += dp[i-1][j]; } } return dp[S.length()][T.length()]; } }
public int numDistinct(String S, String T) { // array creation int[][] mem = new int[T.length()+1][S.length()+1]; // filling the first row: with 1s for(int j=0; j<=S.length(); j++) { mem[0][j] = 1; } // the first column is 0 by default in every other rows but the first, which we need. for(int i=0; i<T.length(); i++) { for(int j=0; j<S.length(); j++) { if(T.charAt(i) == S.charAt(j)) { mem[i+1][j+1] = mem[i][j] + mem[i+1][j]; } else { mem[i+1][j+1] = mem[i+1][j]; } } } return mem[T.length()][S.length()]; }