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