题目链接:
https://leetcode-cn.com/problems/distinct-subsequences/submissions/
思路:
一道dp的题
状态转移方程为:
if (s[j] == t[i])dp[i][j] = dp[i-1][j-1] = dp[i][j-1] //意思是:如果字符串中对应字符相同,则转移状态,此子字符串在之前的子串集合里出现的次数是上一个子串出现的次数加上该串之前出现的次数(不知道讲清楚没,我是理解的/思考)
else dp[i][j] = dp[i][j-1] 如果不相等,则此单元内肯定是当前子串在集合内出现的次数,也就是上一个单元格的值(因为没有出现新的相同的串)
表格图示如下:
(空子串肯定在所有子串中出现一次,而第一列由于原始字符串为空,则没有相应的出现——语文不好,可能没咋讲清楚。不过看图因该能理解/捂脸)
t \ s | '' | b | a | b | g | b | a | g |
'' | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
b | 0 | 1 | 1 | 2 | 2 | 3 | 3 | 3 |
a | 0 | 0 | 1 | 1 | 1 | 1 | 4 | 4 |
g | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 5 |
下面是源码:
package leetcode; public class NumDistinct { /** * dynamic programming * @param s * @param t * status transfer formula is : * if s==t dp[i][j] = dp[i-1][j-1] + dp[i][j-1]:means the sum of combinations and already exist * if s!=t dp[i][j] = dp[i][j-1] * @return */ public int numDistinct(String s, String t) { if(s.length()==0&&t.length()==0)return 0; int[][] dp = new int[t.length()+1][s.length()+1];//build status transfer array for(int i = 0;i<dp.length;++i){ dp[i][0] = 0; } for(int j = 0;j<dp.length;++j){ dp[0][j] = 1; }//initialize char[] s_temp = s.toCharArray(); char[] t_temp = t.toCharArray(); for(int i = 1;i<dp.length;++i){ for(int j = 1;j<dp[0].length;++j){ if(t_temp[i-1]==s_temp[j-1]) dp[i][j] = dp[i-1][j-1] + dp[i][j-1]; else dp[i][j] = dp[i][j-1]; } } return dp[s.length()][t.length()]; } }
代码已ac
希望对大家有所帮助
以上