給定一個字符串 S 和一個字符串 T,計算在 S 的子序列中 T 出現的個數。數組
一個字符串的一個子序列是指,經過刪除一些(也能夠不刪除)字符且不干擾剩餘字符相對位置所組成的新字符串。(例如,"ACE"
是 "ABCDE"
的一個子序列,而 "AEC"
不是)spa
示例 1:3d
輸入: S = , T = 解釋: 以下圖所示, 有 3 種能夠從 S 中獲得 。 (上箭頭符號 ^ 表示選取的字母) ^^^^ ^^ ^^ ^^^^ ^^^ ^^^ "rabbbit""rabbit" 輸出: 3"rabbit" 的方案rabbbitrabbbitrabbbit
示例 2:code
輸入: S = , T = 解釋: 以下圖所示, 有 5 種能夠從 S 中獲得 。 (上箭頭符號 ^ 表示選取的字母) ^^ ^ ^^ ^ ^ ^^ ^ ^^ ^^^"babgbag""bag" 輸出: 5"bag" 的方案babgbagbabgbagbabgbagbabgbagbabgbag
連接:https://www.nowcoder.com/questionTerminal/ed2923e49d3d495f8321aa46ade9f873
來源:牛客網
blog
咱們須要一個二維數組dp(i)(j)來記錄長度爲i的字串在長度爲j的母串中出現的次數,這裏長度都是從頭算起的,並且遍歷時,保持子串長度相同,先遞增母串長度,母串最長時再增長一點子串長度重頭開始計算母串。 字符串
首先咱們先要初始化矩陣,當子串長度爲0時,全部次數都是1,當母串長度爲0時,全部次數都是0.當母串子串都是0長度時,次數是1(由於都是空,相等)。接着,若是子串的最後一個字母和母串的最後一個字母不一樣,說明新加的母串字母沒有產生新的可能性,能夠沿用該子串在較短母串的出現次數,因此dp(i)(j) = dp(i)(j-1)。若是子串的最後一個字母和母串的最後一個字母相同,說明新加的母串字母帶來了新的可能性,咱們不只算上dp(i)(j-1),也要算上新的可能性。那麼如何計算新的可能性呢,其實就是在既沒有最後這個母串字母也沒有最後這個子串字母時,子串出現的次數,咱們至關於爲全部這些可能性都添加一個新的可能。因此,這時dp(i)(j) = dp(i)(j-1) + dp(i-1)(j-1)。下圖是以rabbbit和rabbit爲例的矩陣示意圖。計算元素值時,當末尾字母同樣,其實是左方數字加左上方數字,當不同時,就是左方的數字。 get
動歸思想。加上一個新字母后,匹配的組數應該等於s、t都去掉該新字母成功匹配數 + s不加新字母時已經成功的組數it
個人:io
public int numDistinct(String s, String t) { if (s == null || t == null || s.length()==0 || t.length() ==0) { return 0; } int[][] dp = new int[t.length()+1][s.length()+1]; //初始化矩陣,當子串長度爲0時,全部次數都是1,當母串長度爲0時,全部次數都是0.空串""也是子串 for (int i=0;i<t.length();i++) { dp[i][0] = 0; } for (int i=0;i<s.length();i++) { dp[0][i] = 1; } for (int i=1;i<=t.length();i++) { for (int j=1;j<=s.length();j++) { if (s.charAt(j-1) != t.charAt(i-1)) dp[i][j] = dp[i][j-1]; else dp[i][j] = dp[i-1][j-1] + dp[i][j-1]; } } return dp[t.length()][s.length()]; }