day58 回文子串 最长回文子序列

2024-04-16 00:52

本文主要是介绍day58 回文子串 最长回文子序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目1:647 回文子串

题目链接:647 回文子串

题意

统计字符串s中回文子串的数目

回文子串是正着读和倒过来读一样的字符串    子串是连续字符组成的一个序列

动态规划

动规五部曲

1)dp数组及下标i的含义

dp[i][j]  表示 [s[i],s[j]]范围内的子串是否是回文串   若是则dp[i][j] = true

2)dp数组初始化

根据dp数组定义  dp[i][j] = false;

3)递推公式

if(s[i] != s[j])  肯定不是回文子串,对最终的结果没有什么影响,所以不做考虑

if(s[i] == s[j])  这个是大前提   考虑出现回文子串的情况:

情况1    i == j  指向了同一个元素  此时只有1个元素作为子串  是回文子串   dp[i][j] = true;

情况2    j - i == 1  相邻元素相同,是一个回文子串  dp[i][j] = true;

情况3    j - i > 1    取决于[s[i+1],s[j-1]]是否是回文子串  if(dp[i+1][j-1] == true)  dp[i][j]=true;

4)遍历顺序

根据递推公式,从下往上遍历  从左往右遍历

for(int i = s.size()-1; i >= 0; i--){

        for(int j = i; j < s.size(); j++){

        }

}

5)打印dp数组

代码

class Solution {
public:int countSubstrings(string s) {//定义dp数组  初始化dp数组vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));int result = 0;for(int i = s.size() - 1; i >= 0; i--){for(int j = i; j < s.size(); j++){if(s[i] == s[j]){if(i == j){dp[i][j] = true;result++;} else if(j - i == 1){dp[i][j] = true;result++;}else if(j - i > 1){if(dp[i+1][j-1] == true){dp[i][j] = true;result++;}}}//cout<< "i=" << i << " " << "j=" << j << " " << dp[i][j] << " " << "result=" <<result << endl;}}return result;}
};
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n^2)

题目2:516 最长回文子序列

题目链接:516 最长回文子序列

题意

找出回文子序列的最长长度  

子序列可以在不改变元素顺序的情况下,删除/不删除某个字符形成的

和647 最长回文子串的区别是,这个可以选择删除中间元素,只要不改变原顺序

动态规划

动规五部曲

1)dp数组及下标i的含义

dp[i][j]  在[s[i],s[j]] 内最长回文子串的长度

2)dp数组初始化

i==j 时,指向同一个元素  dp[i][i] = 1

其他下标对应的dp[i][j]初始化为0

3)递推公式

if(s[i] == s[j])  dp[i][j] = dp[i+1][j-1] + 2

else dp[i][j] = max(dp[i+1][j],dp[i][j-1])

4)遍历顺序

根据递推公式  从下往上遍历 从左往右遍历

for(int i = s.size(); i >= 0; i--){

        for(int j = i+1; j <s.size(); j++){

        }

}   两个for循环不能颠倒顺序,因为j的状态依赖于i的状态

5)打印dp数组

代码

class Solution {
public:int longestPalindromeSubseq(string s) {//定义dp数组 初始化vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));for(int i = 0; i < s.size(); i++) dp[i][i] = 1;for(int i = s.size() - 1; i >= 0; i--){for(int j = i + 1; j < s.size(); j++){if(s[i] == s[j]) dp[i][j] = dp[i+1][j-1] + 2;else {dp[i][j] = max(dp[i+1][j-1], max(dp[i][j-1], dp[i+1][j]));}}}return dp[0][s.size() - 1];}
};
  • 时间复杂度: O(n^2)
  • 空间复杂度: O(n^2)

这篇关于day58 回文子串 最长回文子序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/907391

相关文章

poj2406(连续重复子串)

题意:判断串s是不是str^n,求str的最大长度。 解题思路:kmp可解,后缀数组的倍增算法超时。next[i]表示在第i位匹配失败后,自动跳转到next[i],所以1到next[n]这个串 等于 n-next[n]+1到n这个串。 代码如下; #include<iostream>#include<algorithm>#include<stdio.h>#include<math.

poj3261(可重复k次的最长子串)

题意:可重复k次的最长子串 解题思路:求所有区间[x,x+k-1]中的最小值的最大值。求sa时间复杂度Nlog(N),求最值时间复杂度N*N,但实际复杂度很低。题目数据也比较水,不然估计过不了。 代码入下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

csu1328(近似回文串)

题意:求近似回文串的最大长度,串长度为1000。 解题思路:以某点为中心,向左右两边扩展,注意奇偶分开讨论,暴力解即可。时间复杂度O(n^2); 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#inclu

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

hihocoder1050 : 树中的最长路

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅仅可以拼凑成一棵二叉树!还可以拼凑成一棵多叉树——好吧,其实就是更为平常的树而已。 但是不管怎么说,小Ho喜爱的玩具又升级换代了,于是他更加爱不释手(其实说起来小球和木棍有什么好玩的是吧= =)。小Ho手

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

计蒜客 Skiing 最长路

In this winter holiday, Bob has a plan for skiing at the mountain resort. This ski resort has MM different ski paths and NN different flags situated at those turning points. The ii-th path from the

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr