您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++怎么解決不同的子序列問題”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++怎么解決不同的子序列問題”吧!
Example 1:
Input: S =
"rabbbit"
, T =
"rabbit"
Output: 3
Explanation:
As shown below, there are 3 ways you can generate "rabbit" from S.
(The caret symbol ^ means the chosen letters)
rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^
Example 2:
Input: S =
"babgbag"
, T =
"bag"
Output: 5
Explanation:
As shown below, there are 5 ways you can generate "bag" from S.
(The caret symbol ^ means the chosen letters)
babgbag
^^ ^
babgbag
^^ ^
babgbag
^ ^^
babgbag
^ ^^
babgbag
^^^
看到有關字符串的子序列或者配準類的問題,首先應該考慮的就是用動態規劃 Dynamic Programming 來求解,這個應成為條件反射。而所有 DP 問題的核心就是找出狀態轉移方程,想這道題就是遞推一個二維的 dp 數組,其中 dp[i][j] 表示s中范圍是 [0, i] 的子串中能組成t中范圍是 [0, j] 的子串的子序列的個數。下面我們從題目中給的例子來分析,這個二維 dp 數組應為:
? r a b b b i t
? 1 1 1 1 1 1 1 1
r 0 1 1 1 1 1 1 1
a 0 0 1 1 1 1 1 1
b 0 0 0 1 2 3 3 3
b 0 0 0 0 1 3 3 3
i 0 0 0 0 0 0 3 3
t 0 0 0 0 0 0 0 3
首先,若原字符串和子序列都為空時,返回1,因為空串也是空串的一個子序列。若原字符串不為空,而子序列為空,也返回1,因為空串也是任意字符串的一個子序列。而當原字符串為空,子序列不為空時,返回0,因為非空字符串不能當空字符串的子序列。理清這些,二維數組 dp 的邊緣便可以初始化了,下面只要找出狀態轉移方程,就可以更新整個 dp 數組了。我們通過觀察上面的二維數組可以發現,當更新到 dp[i][j] 時,dp[i][j] >= dp[i][j - 1] 總是成立,再進一步觀察發現,當 T[i - 1] == S[j - 1] 時,dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1],若不等, dp[i][j] = dp[i][j - 1],所以,綜合以上,遞推式為:
dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0)
根據以上分析,可以寫出代碼如下:
class Solution { public: int numDistinct(string s, string t) { int m = s.size(), n = t.size(); vector<vector<long>> dp(n + 1, vector<long>(m + 1)); for (int j = 0; j <= m; ++j) dp[0][j] = 1; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { dp[i][j] = dp[i][j - 1] + (t[i - 1] == s[j - 1] ? dp[i - 1][j - 1] : 0); } } return dp[n][m]; } };
感謝各位的閱讀,以上就是“C++怎么解決不同的子序列問題”的內容了,經過本文的學習后,相信大家對C++怎么解決不同的子序列問題這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。