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_i.

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.
 class Solution {
public int countPalindromicSubsequences(String S) {
Map<String, Set<String>> _seqMap = new HashMap<>();
return findPalindromesHelper(S, _seqMap).size();
} private Set<String> findPalindromesHelper(String s, Map<String, Set<String>> _seqMap) {
Set<String> result = _seqMap.get(s);
if (result != null) {
return result;
}
int len = s.length();
result = new HashSet<String>();
if (len < ) {
return result;
}
if (len == ) {
result.add(s);
return result;
}
result.addAll(findPalindromesHelper(s.substring(, len - ), _seqMap));
result.addAll(findPalindromesHelper(s.substring(, len), _seqMap));
if (s.charAt() == s.charAt(len - )) {
Set<String> subSet = findPalindromesHelper(s.substring(, len - ), _seqMap);
String head = s.substring(, );
for (String s1 : subSet) {
result.add(head + s1 + head);
}
result.add(head + head);
}
_seqMap.put(s, result);
return result;
}
}
 class Solution {
public int countPalindromicSubsequences(String s) {
int len = s.length();
int[][] dp = new int[len][len]; char[] chs = s.toCharArray();
for (int i = ; i < len; i++) {
dp[i][i] = ; // Consider the test case "a", "b" "c"...
} for (int distance = ; distance < len; distance++) {
for (int i = ; i < len - distance; i++) {
int j = i + distance;
if (chs[i] == chs[j]) {
int low = i + , high = j - ;
while (low <= high && chs[low] != chs[j]) {
low++;
}
while (low <= high && chs[high] != chs[j]) {
high--;
}
if (low > high) {
/*
* consider the string from i to j is "a...a" "a...a"... where there is no
* character 'a' inside the leftmost and rightmost 'a'
*
* eg: "aba" while i = 0 and j = 2: dp[1][1] = 1 records the palindrome{"b"},
* the reason why dp[i + 1][j - 1] * 2 counted is that we count dp[i + 1][j - 1]
* one time as {"b"}, and additional time as {"aba"}. The reason why 2 counted
* is that we also count {"a", "aa"}. So totally dp[i][j] record the palindrome:
* {"a", "b", "aa", "aba"}.
*/
dp[i][j] = dp[i + ][j - ] * + ;
} else if (low == high) {
/*
* consider the string from i to j is "a...a...a" where there is only one
* character 'a' inside the leftmost and rightmost 'a'
*
* eg: "aaa" while i = 0 and j = 2: the dp[i + 1][j - 1] records the palindrome
* {"a"}. the reason why dp[i + 1][j - 1] * 2 counted is that we count dp[i +
* 1][j - 1] one time as {"a"}, and additional time as {"aaa"}. the reason why 1
* counted is that we also count {"aa"} that the first 'a' come from index i and
* the second come from index j. So totally dp[i][j] records {"a", "aa", "aaa"}
*/
dp[i][j] = dp[i + ][j - ] * + ;
} else {
/*
* consider the string from i to j is "a...a...a... a" where there are at least
* two character 'a' close to leftmost and rightmost 'a'
*
* eg: "aacaa" while i = 0 and j = 4: the dp[i + 1][j - 1] records the
* palindrome {"a", "c", "aa", "aca"}. the reason why dp[i + 1][j - 1] * 2
* counted is that we count dp[i + 1][j - 1] one time as {"a", "c", "aa",
* "aca"}, and additional time as {"aaa", "aca", "aaaa", "aacaa"}. Now there is
* duplicate : {"aca"}, which is removed by deduce dp[low + 1][high - 1]. So
* totally dp[i][j] record {"a", "c", "aa", "aca", "aaa", "aaaa", "aacaa"}
*/
dp[i][j] = dp[i + ][j - ] * - dp[low + ][high - ];
}
} else {
dp[i][j] = dp[i][j - ] + dp[i + ][j] - dp[i + ][j - ]; // s.charAt(i) != s.charAt(j)
}
dp[i][j] = dp[i][j] < ? dp[i][j] + : dp[i][j] % ;
}
}
return dp[][len - ];
}
}

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. [Swift]LeetCode730. 统计不同回文子字符串 | Count Different Palindromic Subsequences

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

  4. 730. Count Different Palindromic Subsequences

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

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

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

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

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

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

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

  8. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

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

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

随机推荐

  1. Navicat创建连接

    https://blog.csdn.net/suprezheng/article/details/90037702 以下是不用创建直接可用的

  2. 怎么把word文档粘贴到编辑器里啊?

    很多时候我们用一些管理系统的时候,发布新闻.公告等文字类信息时,希望能很快的将word里面的内容直接粘贴到富文本编辑器里面,然后发布出来.减少排版复杂的工作量. 下面是借用百度doc 来快速实现这个w ...

  3. vue-element-admin平时使用归纳

    message提示的使用 import { Message } from 'element-ui'; Message({ message: res.data.message || 'Error', t ...

  4. [vim]多行注释和多行删除

    vim中多行注释和多行删除命令,这些命令也是经常用到的一些小技巧,可以大大提高工作效率. 1.多行注释: 首先按esc进入命令行模式下,按下Ctrl + v,进入列(也叫区块)模式; 在行首使用上下键 ...

  5. DOM元素

    元素的三种创建方法 1.doumrnt.write(可以写类名,各种表情属性)       script写在哪里就创建在哪 <button>点我</button> <sc ...

  6. HDU 4635 Strongly connected ——(强连通分量)

    好久没写tarjan了,写起来有点手生,还好1A了- -. 题意:给定一个有向图,问最多添加多少条边,让它依然不是强连通图. 分析:不妨考虑最大时候的临界状态(即再添加一条边就是强连通图的状态),假设 ...

  7. 使用io/ioutil进行读写文件

    读文件: package main import ( "fmt" "io/ioutil" ) func main() { b, err := ioutil.Re ...

  8. 预处理、const、static与sizeof-为什么要引入内联函数

    1:引入内联函数的主要目的是,用它替代C语言中表达形式的宏定义来解决程序中函数调用的效率问题.在C语言里可以使用如下的宏定义: #define ExpressionName(Var1,Var2) (V ...

  9. hibernate持久化类中,修改字符串长度时,注意的问题

    在使用hibernate注解修饰字符串长度时,如果一开始没有把String类型的变量长度设计好,在网数据库插入数据时,容易造成字段长度超出错误,这时候需要修改@Column里length的大小.如果使 ...

  10. 【转载】详解CI、CD相关概念

    在软件的编译发布的过程中,经常能够看到CI.CD这样的词语.其实他们是专业的缩写短语,这里介绍下他们的概念和区别. 敏捷软件开发 敏捷软件开发,英文全称:Agile software developm ...