730 Count Different Palindromic Subsequences數組
Given a string S, find the number of different non-empty palindromic subsequences in S, and return that number modulo 10^9 + 7
.spa
A subsequence of a string S is obtained by deleting 0 or more characters from S.code
A sequence is palindromic if it is equal to the sequence reversed.遞歸
Two sequences A_1, A_2, ...
and B_1, B_2, ...
are different if there is some i
for which A_i != B_i
.ip
Example 1:leetcode
Input: S = 'bccb' Output: 6 Explanation: The 6 different non-empty palindromic subsequences are 'b', 'c', 'bb', 'cc', 'bcb', 'bccb'. Note that 'bcb' is counted only once, even though it occurs twice.
Example 2:字符串
Input: S = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba' Output: 104860361 Explanation: There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 10^9 + 7.
Note:get
The length of S
will be in the range [1, 1000]
. Each character S[i]
will be in the set {'a', 'b', 'c', 'd'}
.string
雖然題目只要求四個字母,但咱們擴展廣泛性,這裏就作二十六個字母的。帶記憶數組和動態規劃的本質是差很少的。帶記憶數組memo的遞歸解法,這種解法的思路是一層一層剝洋蔥,好比"bccb",按照字母來剝,先剝字母b,肯定最外層"b _ _ b",這會產生兩個迴文子序列"b"和"bb",而後遞歸進中間的部分,把中間的迴文子序列個數算出來加到結果res中,而後開始剝字母c,找到最外層"cc",此時會產生兩個迴文子序列"c"和"cc",而後因爲中間沒有字符串了,因此遞歸返回0,按照這種方法就能夠算出全部的迴文子序列了。it
class Solution { public: int countPalindromicSubsequences(string S) { int len = S.size(); vector<vector<int>> dp(len+1, vector<int>(len+1, 0)); vector<vector<int>> ch(26, vector<int>()); for (int i = 0; i < len; i++) { ch[S[i]-'a'].push_back(i); } return calc(S, ch, dp, 0, len); } int calc(string S, vector<vector<int>>& ch, vector<vector<int>>& dp, int start, int end) { if (start >= end) return 0; if (dp[start][end] > 0) return dp[start][end]; long ans = 0; for (int i = 0; i < 26; i++) { if (ch[i].empty()) continue; auto new_start = lower_bound(ch[i].begin(), ch[i].end(), start); auto new_end = lower_bound(ch[i].begin(), ch[i].end(), end) - 1; if (new_start == ch[i].end() || *new_start >= end) continue; ans++; if (new_start != new_end) ans++; ans += calc(S, ch, dp, *new_start+1, *new_end); } dp[start][end] = ans % int(1e9+7); return dp[start][end]; } };