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;
        
    }
}

 

posted @   风乐  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
点击右上角即可分享
微信分享提示