Given a string S and a string T, count the number of distinct subsequences of S which equals T. 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字符串。例如rabbbit中含有3个rabbit字符串,经过分别删除第1,2,3个b。面试
这时一道典型的DP题。也就是说,咱们须要经过一个数据结构来记录临时结果从而支持咱们在已知前面几个状况的场景下对后续状况进行计算。在这道题目中,若是咱们想要计算S中含有几个T(假设S长度为n,T长度为m),那么咱们只须要知道S[0...n]含有几个T[0...m-1]以及S[0...n-1]含有几个T[0...m-1]。
从中概括出最广泛的场景,也就是若是想要计算S[0...i]含有几个T[0...j],能够从如下两种场景来考虑:数组
1.S[i]!=T[j] 那么S[0...i]包含的T[0...j]的数量等价于S[0...i-1]包含T[0...j]的数量。 2.S[i]==T[j] 那么S[0...i]包含的T[0...j]的数量等价于S[0...i-1]包含T[0...j]的数量**加上**S[0...i-1]包含T[0...j-1]的数量
再来考虑初始的极端状况微信
1.j==0,此时S为一个空字符串,那么S的任何自字符串都包含一个惟一空字符串 2.i==0&&j!=0 此时S为非空字符串而T为空字符串,那么S包含0个T
以后咱们采用intm+1来存储临时变量,其中inti+1表示S[0...j]含有几个T[0...i]
代码以下:数据结构
public int numDistinct(String s, String t) { if(s==null || t==null) return 0; if(t.isEmpty()) return 1; int[][] temp = new int[t.length()+1][s.length()+1]; for(int i = 0 ; i<s.length()+1 ; i++) temp[0][i] = 1; for(int i = 0; i<t.length() ; i++){ for(int j = 1 ; j<s.length()+1 ; j++){ if(t.charAt(i)==s.charAt(j-1)){ temp[i+1][j] = temp[i+1][j-1]+ temp[i][j-1]; }else{ temp[i+1][j] = temp[i+1][j-1]; } } } return temp[t.length()][s.length()]; }
对这段代码的优化咱们能够考虑不采用二维数组而采用一维数组的方式来存储过程值:优化
public int numDistinct2(String s, String t) { int[] array = new int[s.length()+1]; int prev = 1; for(int i = 0 ; i<s.length()+1 ; i++) array[i] = 1; for(int i = 0 ; i<t.length() ; i++){ for(int j = 0 ; j<s.length()+1 ; j++){ int temp = array[j]; if(j==0) array[j] = 0; else if(t.charAt(i) == s.charAt(j-1)){ array[j] = array[j-1]+prev; }else{ array[j] = array[j-1]; } prev = temp; } } return array[s.length()]; }
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注个人微信公众号!将会不按期的发放福利哦~spa