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
.A subsequence of a string S is obtained by deleting 0 or more characters from S.
A sequence is palindromic if it is equal to the sequence reversed.
Two sequences
A_1, A_2, ...
andB_1, B_2, ...
are different if there is somei
for whichA_i != B_
Example 1:
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:
- The length of
S
will be in the range[1, 1000]
.- Each character
S[i]
will be in the set{'a', 'b', 'c', 'd'}
.
Approach #1: DFS + Memeory. [C++][MLE]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class Solution { public : int countPalindromicSubsequences(string S) { return count(S); } private : unordered_map<string, long > memo; static constexpr long mod = 1000000007; int count( const string& s) { if (s.empty()) return 0; if (s.length() == 1) return 1; if (memo[s] > 0) return memo[s]; int len = s.length(); long ans = 0; if (s[0] == s[len-1]) { int l = 1, r = len - 2; while (l <= r && s[l] != s[0]) l++; while (l <= r && s[r] != s[len-1]) r--; if (l > r) ans = count(s.substr(1, len-2))*2 + 2; else if (l == r) ans = count(s.substr(1, len-2))*2 + 1; else ans = count(s.substr(1, len-2))*2 - count(s.substr(l+1, r-l-1)); } else { ans = count(s.substr(0, len-1)) + count(s.substr(1, len-1)) - count(s.substr(1, len-2)); } ans = (ans + mod) % mod; // cout << ans << endl; return memo[s] = ans; } }; |
Approach #2: Optimization. [C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | class Solution { public : int countPalindromicSubsequences(string S) { int len = S.length(); memo = vector< int >(len*(len+1)+1, 0); return count(S, 0, len-1); } private : vector< int > memo; static constexpr long mod = 1000000007; int count( const string& S, int s, int e) { if (s > e) return 0; if (s == e) return 1; int key = s * S.length() + e; if (memo[key] > 0) return memo[key]; int len = S.length(); long ans = 0; if (S[s] == S[e]) { int l = s+1, r = e-1; while (l <= r && S[l] != S[s]) l++; while (l <= r && S[r] != S[e]) r--; if (l > r) ans = count(S, s+1, e-1)*2 + 2; else if (l == r) ans = count(S, s+1, e-1)*2 + 1; else ans = count(S, s+1, e-1)*2 - count(S, l+1, r-1); } else { ans = count(S, s+1, e) + count(S, s, e-1) - count(S, s+1, e-1); } return memo[key] = (ans + mod) % mod; } }; |
Approach #3: DP. [C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class Solution { long mod = 1000000007; public int countPalindromicSubsequences(String S) { int len = S.length(); long [][] dp = new long [len][len]; for ( int i = 0; i < len; ++i) dp[i][i] = 1; for ( int k = 1; k <= len; ++k) { for ( int i = 0; i < len-k; ++i) { int j = i + k; if (S.charAt(i) == S.charAt(j)) { dp[i][j] = dp[i+1][j-1] * 2; int l = i + 1; int r = j - 1; while (l <= r && S.charAt(l) != S.charAt(i)) l++; while (l <= r && S.charAt(r) != S.charAt(j)) r--; if (l > r) dp[i][j] += 2; else if (l == r) dp[i][j] += 1; else dp[i][j] -= dp[l+1][r-1]; } else dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1]; dp[i][j] = (dp[i][j] + mod) % mod; } } return ( int )dp[0][len-1]; } } |
Reference:
__EOF__
![](https://files.cnblogs.com/files/ruruozhenhao/mind-bending-gifs-by-florian-de-looij-1.gif)
本文作者:Veritas des Liberty
本文链接:https://www.cnblogs.com/h-hkai/p/10524409.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/h-hkai/p/10524409.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
永远渴望,大智若愚(stay hungry, stay foolish)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
2018-03-13 D - Back and Forth(模拟)
2018-03-13 I - 一次元リバーシ / 1D Reversi(水题)