问题描述:java
<pre> 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. </pre>code
问题反复读了几遍感受才理解。首先想到的是用递归的方法试试:orm
public class DistinctSubsequences { private int numDS = 0; public int numDistinct(String S, String T) { numDS = 0; searchSequence(S, T); return numDS; } private void searchSequence(String S, String T) { //System.out.println("searchSequence(" + S + ", " + T + ")"); if (S.length() < T.length()) { return; } if (T.length() == 0) { numDS++; return; } int slen = S.length(); for (int i = 0; i < slen; i++) { if (S.charAt(i) == getHead(T)) { searchSequence(cutHead(S, i+1), cutHead(T, 1)); } } } public String cutHead(String s, int begin) { return s.substring(begin, s.length()); } public char getHead(String s) { return s.charAt(0); } }
提交后报出超时的错误。感受上应该能够用动态规划来作,由于毕业找工做时,发现不少用递归作的题最终解答都是动态规划,想了好久,发现能够这样:递归
public class DistinctSubsequences { private int numDS = 0; public int numDistinct(String S, String T) { return dpSearchSequence(S, T); } private int dpSearchSequence(String S, String T) { int slen = S.length(); int tlen = T.length(); if (slen < tlen || slen == 0 || tlen == 0) return 0; int dp[][] = new int[tlen][slen]; for (int i = 0; i < tlen; i++) { for (int j = i; j < slen; j++) { if (T.charAt(i) == S.charAt(j)) { if (i > 0) { dp[i][j] = dp[i-1][j-1] // S[0..j-1] 中 T[0..i-1] 出现的次数 + dp[i][j-1]; // S[0..j-1] 中 T[0..i] 出现的次数 // 例如:计算 abcc 中子序列 abc 次数,能够这样递归: // recur(abcc, abc) { // return recur(abc, ab) + recur(abc, abc) // } } else { if (j > 0) { dp[i][j] = dp[i][j-1] + 1; } else { dp[i][j] = 1; } } } else { if (j > 0) { dp[i][j] = dp[i][j-1]; } else { dp[i][j] = 0; } } } } return dp[tlen-1][slen-1]; } }
对动态规划的题仍是很不熟,仍是得多看看啊。rem