647.回文子串
题目
给你一个字符串 s
,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
示例 1:
输入:s = "abc" 输出:3 解释:三个回文子串: "a", "b", "c"
示例 2:
输入:s = "aaa" 输出:6 解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
代码(动态规划)
class Solution {
public int countSubstrings(String s) {
int len = s.length();
int count = 0; //记录回文子串的个数
//dp[i][j]表示s(i,j)子串是不是回文子串
//是,true,否,false
boolean[][] dp = new boolean[len][len];
//初始化:默认false
//遍历顺序:从下到上,从左到右
for(int i=len-1; i >=0; i--){
for(int j=i; j <= len -1 ; j++){
//i和j字母相同
if(s.charAt(i) == s.charAt(j)){
//i=j 一个字母a 肯定是回文串
//i=j-1 两个字母aa 也是回文串
if(j - i <= 1){
dp[i][j] = true;
count++;
}
//3个及以上字母 aba 要看中间b是不是回文串(左下方)
else{
dp[i][j] = dp[i+1][j-1]; //左下方
if(dp[i][j]){
count++;
}
}
}
//i和j字母不相同,肯定不是回文子串
else{
dp[i][j] = false;
}
}
}
return count;
}
}
516.最长回文子序列
题目
给你一个字符串 s
,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
示例 1:
输入:s = "bbbab" 输出:4 解释:一个可能的最长回文子序列为 "bbbb" 。
示例 2:
输入:s = "cbbd" 输出:2 解释:一个可能的最长回文子序列为 "bb" 。
代码
class Solution {
public int longestPalindromeSubseq(String s) {
int len = s.length();
//dp[i][j]表示s(i,j)子串的最长回文子序列
int[][] dp = new int[len][len];
//初始化:单个字母(对角线)的回文长度都是1
for(int i=0; i < len; i++){
dp[i][i] = 1;
}
//遍历顺序:从下到上,从左到右
for(int i=len-1; i >= 0; i--){
for(int j=i+1; j <= len-1; j++){
//头尾ij字母一样
if(s.charAt(i) == s.charAt(j)){
dp[i][j] = dp[i+1][j-1] + 2; //中间长度+2
}
//头尾ij字母不一样
else{
//abbbb,头尾ij是ab,中间是bbb,取后面[i+1,j],下方
//bbbba,头尾ij是ba,中间是bbb,取前面[i,j-1],左方
dp[i][j] = Math.max(dp[i+1][j],dp[i][j-1]);
}
}
}
//返回s[0,len-1]就是s的最长回文子序列
return dp[0][len-1];
}
}