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, ...
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的更多相关文章
- leetcode 730 Count Different Palindromic Subsequences
题目链接: https://leetcode.com/problems/count-different-palindromic-subsequences/description/ 730.Count ...
- LN : leetcode 730 Count Different Palindromic Subsequences
lc 730 Count Different Palindromic Subsequences 730 Count Different Palindromic Subsequences Given a ...
- [Swift]LeetCode730. 统计不同回文子字符串 | Count Different Palindromic Subsequences
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- 730. Count Different Palindromic Subsequences
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- 【LeetCode】730. Count Different Palindromic Subsequences 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 记忆化搜索 动态规划 日期 题目地址:https:/ ...
- [LeetCode] Count Different Palindromic Subsequences 计数不同的回文子序列的个数
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- [LeetCode] 730. Count Different Palindromic Subsequences 计数不同的回文子序列的个数
Given a string S, find the number of different non-empty palindromic subsequences in S, and return t ...
- Swift LeetCode 目录 | Catalog
请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift 说明:题目中含有$符号则为付费题目. 如 ...
- LeetCode All in One题解汇总(持续更新中...)
突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...
随机推荐
- Window Service安装不成功
1. 加Winsow Service 2. 加Setup Project Add -> Project Output , 选中Primary output from Winsow Serv ...
- git log/show/HEAD step(2)
git log can see all commit log #git logcommit 2737cfa37f81810072f074dcf19964be0a5eea2e (HEAD -> m ...
- HDU 5734 Acperience ( 数学公式推导、一元二次方程 )
题目链接 题意 : 给出 n 维向量 W.要你构造一个 n 维向量 B = ( b1.b2.b3 ..... ) ( bi ∈ { +1, -1 } ) .然后求出对于一个常数 α > 0 使得 ...
- [Loj] 数列分块入门 1 - 9
数列分块入门 1 https://loj.ac/problem/6277 区间加 + 单点查询 #include <iostream> #include <cstdio> #i ...
- 【线性代数】1-2:点乘和长度(Dot Products and Length)
title: [线性代数]1-2:点乘和长度(Dot Products and Length) toc: true categories: Mathematic Linear Algebra date ...
- IDT系列:(一)初探IDT,Interrupt Descriptor Table,中断描述符表
原文: IDT系列:(一)初探IDT,Interrupt Descriptor Table,中断描述符表 IDT,Interrupt Descriptor Table,中断描述符表是CPU用来处理中 ...
- 堡垒机前戏——paramiko
提要:在写堡垒机之前,我们必须要了解paramiko这个第三方库.有关于python的第三方库的安装很简单,可以自行百度. 该模块基于SSH用于连接远程服务器并执行相关操作. SSHClient 用于 ...
- 解决 go get golang.org/x/* 拉取失败问题
go get -u -v golang.org/x/text 有时候会因为网络问题,导致失败. 在不用代理的情况下,可以使用以下方案. golang.org,他们在github上有一个镜像库 以 go ...
- LeetCode 279. 完全平方数(Perfect Squares)
题目描述 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n.你需要让组成和的完全平方数的个数最少. 示例 1: 输入: n = 12 输出: 3 解释 ...
- 数据结构之队列(Queue)
1,队列的定义 队列:是一种先进先出的数据结构,如下图所示,现进去的数据在队列前面(front),先出队列,后进入队列的数据在后面(rear),后出队列. 队列常用操作: q=Queue() #创建队 ...