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, ... and B_1, B_2, ... are different if there is some i for which A_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]

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++]

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++]

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:

http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-730-count-different-palindromic-subsequences/

730. Count Different Palindromic Subsequences的更多相关文章

  1. leetcode 730 Count Different Palindromic Subsequences

    题目链接: https://leetcode.com/problems/count-different-palindromic-subsequences/description/ 730.Count ...

  2. LN : leetcode 730 Count Different Palindromic Subsequences

    lc 730 Count Different Palindromic Subsequences 730 Count Different Palindromic Subsequences Given a ...

  3. [LeetCode] 730. Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  4. 【LeetCode】730. Count Different Palindromic Subsequences 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 记忆化搜索 动态规划 日期 题目地址:https:/ ...

  5. [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  6. [Swift]LeetCode730. 统计不同回文子字符串 | Count Different Palindromic Subsequences

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  7. Count Different Palindromic Subsequences

    Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...

  8. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

  9. leetcode 学习心得 (4)

    645. Set Mismatch The set S originally contains numbers from 1 to n. But unfortunately, due to the d ...

随机推荐

  1. jxl 创建excel

    public static void performanceExcel(String sCurrPath,List<Record> list, String begin,String en ...

  2. Spring框架的事务管理之声明式事务管理的类型

    1. 声明式事务管理又分成两种方式 * 基于AspectJ的XML方式(重点掌握)(具体内容见“https://www.cnblogs.com/wyhluckdog/p/10137712.html”) ...

  3. Golang之redis

    redis是个开源的高性能的key-value的内存数据库,可以把它当成远程的数据结构. 支持的value类型非常多,比如string.list(链表).set(集合). hash表等等 redis性 ...

  4. Canvas游戏计算机图形教程

    TechbrooD   主站 WOW 登录   注册 0首页 1简介 1.1WWW 技术变迁和生态 1.2WWW 学习建议 1.3WWW 互联网基础知识 1.4WWW Web 1.5 WWW Web ...

  5. 一、消息队列之ActiveMQ的安装、配置和C#样例代码

    最近有时间了,研究一下消息队列ActvieMQ,结合自己的实践和网上的一些大家内容,整理如下,所有步骤和链接均是正确的. 1.ActiveMQ ActiveMQ 是Apache出品,最流行的,能力强劲 ...

  6. VMware workstation 设定开机引导等待时间

    找到虚拟机磁盘文件所在的目录,编辑里面的扩展名为vmx文件,记事本即可操作,在末尾加入如下一行: bios.bootDelay = "20000" 这里的数字是毫秒,上面例子中的数 ...

  7. memcached centos启动笔记

    root情况下命令行输入 apt-get install memcached 自动安装 不熟悉的情况下 可能找不到改程序所在目录 使用 find / -name memcached 从根目录开始寻找 ...

  8. 06 数据库入门学习-视图、sql注入、事务、存储过程

    一.视图 1.什么是视图 视图本质是一张虚拟的表 2.为什么要用 为了原表的安全 只要有两大功能 1.隐藏部分数据,开放指定数据 2.视图可以将查询结果保存,减少sql语句的次数 特点: 1.视图使用 ...

  9. spring mvc 用cookie和拦截器实现自动登录(/免登录)

    Cookie/Session机制详解:http://blog.csdn.net/fangaoxin/article/details/6952954 SpringMVC记住密码功能:http://blo ...

  10. 着重基础之—Java 8 Comparator: How to Sort a List (List排序)

    着重基础之—Java 8 Comparator: How to Sort a List (List排序) 首先申明,这篇博客的内容不是我自己的知识,我是从国外网站搬来的,原因有二:1是因为大天朝对网络 ...