647. 回文子串(leetcode)
https://leetcode.cn/problems/palindromic-substrings/
经典题,本题有双指针和dp两种做法,dp的定义是f[i][j]表示s[i:j]是回文串
容易联想到递推方程f[i][j]=f[i+1][j-1] && s[i]==s[j]
又因为1个字符或者两个相等的字符一定是回文串,因此当s[i]==s[j]时,且j-i<=1,则意味着子串的长度<=2,此时一定为回文串.f[i][j]=true
class Solution {
public int countSubstrings(String s) {
// f[i][j]表示[i:j]这个串是回文串
// 分析题意可知 若j-i <= 1 ,且s[i]=s[j],则一定是回文串
// 以s[i],s[j]是否相等,子串是否是回文串 来划分子集
// 若相等,且j-i<=1,一定是回文串
// 若相等,且[i+1:j-1]是回文串,即f[i+1][j-1]==true,则一定是回文串
// f[i][j]=if(s[i]==s[j] && j-i<=1) true
// else if(s[i]==s[j] && f[i+1][j-1]) true;
// 由于递推式含f[i+1][j],因此需要更改遍历顺序才能正确推导,由小集合递推大集合
// 且无需初始化
int res=0;
boolean[][] f=new boolean[1010][1010];
for(int j=1;j<=s.length();j++)
{
for(int i=1;i<=j;i++)
{
if(s.charAt(i-1)==s.charAt(j-1) && (j-i<=1 || f[i+1][j-1] ) )
{
f[i][j]=true;
res++;
}
}
}
return res;
}
}
class Solution {
public int countSubstrings(String s) {
// 双指针解法
// 思路是遍历每一个元素,从遍历的当前元素左右双指针扫描,检查是否回文,回文即res++
// 这里有两种情况,一种回文是奇数,则从长度1开始扩散,一种回文偶数,从长度2扩散
// 即中心点分为1个,2个两种情况
int res=0;
for(int i=0;i<s.length();i++)
{
// 奇数
for(int a=i,b=i;a>=0 && b<s.length() && s.charAt(a)==s.charAt(b);)
{
res++;
a--;
b++;
}
// 偶数
for(int a=i,b=i+1;a>=0 && b<s.length() && s.charAt(a)==s.charAt(b);)
{
res++;
a--;
b++;
}
}
return res;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏