LeetCode刷题最好按照标签归类来刷,本文主要对leetcode上的回文串问题做一个梳理。
Leetcode上回文串经典题如下:
回文串核心问题
什么是回文串
回文字符串指的是字符串从左到右 和从右到左是一样的。
- 单个字符肯定是回文串
- 两个字符如果相等是回文串
- 多个字符,如果首末位相等,中间是回文,那么整体是回文
概括三种情况:
对于一个字符串s,从下标i到j的子串,判断其回文。flag[i][j]表示i~j是否为回文。
s[i]==s[j] &&(flag[i+1][j-1] || j-i<=1)

由此可见flag[i][j]依赖于flag[i+1][j-1],我们要计算出flag[i][j]必须先求出flag[i+1][j-1],而这个位置是在(i,j)的下方,因此我们填充flag这个表格数组的时候遵从的是从左到右从下到上的生成方式。
LC5 最长回文子串
使用动态规划 dp[i] 表示从i到len-1位置的最长回文子串长度。

求出一个dp数组,保存[i,j]是否为回文的信息,对于一个从i到j的子串,如何判断它是否为回文串。
如图1,当固定i=3时,j可以从3到7进行遍历,每次j遍历的过程中会计算出i到j是否是回文,这样再下次计算的时候,直接使用,不用重复计算。
如当i=3,j=5时,s[i]=s[j],且flag[4][4]是true,那么dp[i]此时就可以进行更新,dp[i]=5-3+1=3;当j不断向后继续遍历,dp[i]的值就会不断更新。
/**
**为什么不能从i=0到i=n-1 而是要从i=n-1到i=0因
**flag[i][j]依赖于 flag[i+1][j-1]因此 要先计算出i+1行 ,j-1列才能推算 出i,j
**因此方向为从下到上,从左到右
**/
public String longestPalindrome(String s) {
if(s==null || s.length()==0){
return "";
}
int n=s.length();
boolean[][] flag=new boolean[n][n];
int[] dp=new int[n];
for(int i=0;i<n;i++){
dp[i]=1;
}
char[]t =s.toCharArray();
//记录长度
int res=0;
//记录起始位置
int index=-1;
for(int i=n-1;i>=0;i--){
for(int j=i;j<n;j++){
//[i,j]是回文,dp[i]表示[i,len-1]上的最长回文串,dp[i]有一个初始值
//现在找到了一个 i~j 长度为j-i+1, j一直变化,能够找到以i开头的最大长度
if(t[i]==t[j]&& (j-i<=1||flag[i+1][j-1])){
flag[i][j]=true;
//从i到j是回文,那么[i,len-1]的最长回文 至少有j-i+1;
dp[i]=Math.max(dp[i],j-i+1);
}
}
if(res<dp[i]){
res=dp[i];
index=i;
}
}
return s.substring

本文详细梳理了LeetCode中关于回文串的题目,包括LC5最长回文子串、LC9回文数、LC131分割回文串i和LC132分割回文串ii。介绍了回文串的概念,并通过动态规划和记忆化搜索的方法解决相关问题,还探讨了递归回溯在解题中的应用。
1404

被折叠的 条评论
为什么被折叠?



