当前位置:网站首页>统计字符串中不同回文子序列的个数
统计字符串中不同回文子序列的个数
2022-06-29 00:46:00 【GreyZeng】
统计字符串中不同回文子序列的个数
作者:Grey
原文地址: 统计字符串中不同回文子序列的个数
问题描述
给定一个字符串str,当然可以生成很多子序列,返回有多少个子序列是回文子序列,空序列不算回文,比如,str = “aba”回文子序列有
{a}:0位置上的a
{a}:2位置上的a
{a,a}
{b}
{a,b,a}
所以返回5。
暴力解法
枚举每个子序列,然后判断子序列是否是回文,代码如下
public static int ways1(String str) {
if (str == null || str.length() == 0) {
return 0;
}
char[] s = str.toCharArray();
char[] path = new char[s.length];
return process(str.toCharArray(), 0, path, 0);
}
// 枚举每个位置要或者不要情况下,得到回文子序列的个数是多少
public static int process(char[] s, int si, char[] path, int pi) {
if (si == s.length) {
return isP(path, pi) ? 1 : 0;
}
int ans = process(s, si + 1, path, pi);
path[pi] = s[si];
ans += process(s, si + 1, path, pi + 1);
return ans;
}
// 判断path串中0...pi-1是不是回文
public static boolean isP(char[] path, int pi) {
if (pi == 0) {
return false;
}
int L = 0;
int R = pi - 1;
while (L < R) {
if (path[L++] != path[R--]) {
return false;
}
}
return true;
}
动态规划解
定义二维数组dp,数组长度假设为n
int[][] dp = new int[n][n]
dp[i][j]的含义是:字符串[i...j]区间内可以得到的最多回文子序列个数,所以,dp[0][n-1]的值就是我们需要求的最终答案。
根据dp数组的含义,我们可以得到,二维矩阵dp中的对角线上的值都是1, 对角线上面的位置也可以很容易得出,见如下注释
// 对角线上的值都是1
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
}
// 对角线上面的位置,即dp[i][i+1]上的值
// 如果str[i] == str[i+1],比如:aa,有三个回文子序列,分别是{a},{a},{aa}
// 如果str[i] != str[i+1],比如:ab,有两个回文子序列,分别是 {a},{b}
for (int i = 0; i < n - 1; i++) {
dp[i][i+1] = str[i] == str[i+1] ? 3 : 2;
}
接下来考虑普遍位置dp[i][j],可以有如下几种情况:
情况一,i位置的字符弃而不用,那么dp[i][j] = dp[i+1][j];
情况二,j位置的字符弃而不用,那么dp[i][j] = dp[i][j-1];
基于情况一和情况二,
dp[i][j] = dp[i+1][j] + dp[i][j-1]
这个时候,其实是算重了一部分,算重的部分是dp[i+1][j-1],所以
dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1]
如果str[i] == str[j],则存在情况三,情况三中,str[i]和str[j]可都保留,与区间[i+1...j-1]形成回文串,str[i]也可以单独和str[j]形成一个回文串。所以,情况三
// dp[i][j]分成两部分
// 其中:
// 第一部分:dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] 表示i位置和j位置弃而不用的情况下,得到的答案数
// 第二部分:dp[i + 1][j - 1] + 1 表示在情况三下,同时使用str[i]和str[j]位置得到的答案数
dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + dp[i + 1][j - 1] + 1
动态规划解法的完整代码
public static int ways2(String s) {
if (s == null || s.length() == 0) {
return 0;
}
char[] str = s.toCharArray();
int n = str.length;
int[][] dp = new int[n][n];
// 对角线都是1
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
}
for (int i = 0; i < n - 1; i++) {
dp[i][i + 1] = str[i] == str[i + 1] ? 3 : 2;
}
for (int i = n - 3; i >= 0; i--) {
for (int j = i + 2; j < n; j++) {
// 减去dp[i+1][j-1]是因为算重复了
dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1];
if (str[i] == str[j]) {
// dp[i][j]分成两部分
// 其中:
// 第一部分:dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] 表示i位置和j位置弃而不用的情况下,得到的答案数
// 第二部分:dp[i + 1][j - 1] + 1 表示在情况三下,同时使用str[i]和str[j]位置得到的答案数
dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + dp[i + 1][j - 1] + 1;
}
}
}
return dp[0][n - 1];
}
类似问题
更多
边栏推荐
- Reprint: VTK notes - clipping and segmentation - irregular closed loop clipping -vtkselectpolydata class (black mountain old demon)
- 【UVM】我的 main_phase 都跑完了,为啥 case 无法退出?太不讲道理!
- 个人买同业存单基金选择什么证券公司开户好,更安全
- 如果你会玩这4个自媒体运营工具,副业收入6000+很轻松
- 请问同花顺上开户安全吗
- [MCU club] design of GSM version of range hood based on MCU [simulation design]
- Reprint: VTK notes - clipping and segmentation - 3D curve or geometric cutting volume data (black mountain old demon)
- 卷绕工艺与叠片工艺的对比
- IT治理方面的七个错误,以及如何避免
- 养老年金险是理财产品吗?预期收益在哪看?
猜你喜欢

【leetcode】17. Letter combination of telephone number
![[staff] pedal mark (step on pedal ped mark | release pedal * mark | corresponding pedal command in MIDI | continuous control signal | switch control signal)](/img/2b/e358b22d62ce6d683ed93418ff39fe.jpg)
[staff] pedal mark (step on pedal ped mark | release pedal * mark | corresponding pedal command in MIDI | continuous control signal | switch control signal)

Browser cache library design summary (localstorage/indexeddb)

cocoscreator动态切换SkeletonData实现骨骼更新
How does the JVM bottom layer implement synchronized
![[leetcode] 522. Longest special sequence II violence + double pointer](/img/88/3ddeefaab7e29b8eeb412bb5c3e9b8.png)
[leetcode] 522. Longest special sequence II violence + double pointer

Install MySQL on Windows platform (with Navicat premium 12 "using" tutorial)
【架构师(第三十八篇)】 服务端开发之本地安装最新版 MySQL 数据库

Haskell configuring vs code development environment (june2022)
UI高度自适应的修改方案
随机推荐
浏览器缓存库设计总结(localStorage/indexedDB)
光纤滑环价格过高的原因
Roson's QT journey 80 qurl class
[image registration] improved SAR image registration based on sar-sift with matlab code
Document management.
Is it safe and reliable for qiniu school to help open a securities account? How to drive
企业和IT领导者对创新的误解
Realization of beauty system with MATLAB
What is redis
Mapbox GL loading local publishing DEM data
Depth first search to realize the problem of catching cattle
cocoscreator动态切换SkeletonData实现骨骼更新
If you can play these four we media operation tools, the sideline income of 6000+ is very easy
Click hijack: X-FRAME-OPTIONS is not configured
Is the fund reliable and safe
同期群分析是什么?教你用 SQL 来搞定
HandlerThread使用及原理
手下两个应届生:一个踏实喜欢加班,一个技术强挑活,怎么选??
深度优先搜索实现抓牛问题
Reasons for high price of optical fiber slip ring