最长回文字串

博客围绕用动态规划求解字符串中最长回文子串展开。以字符串“abbba”为例,分析不同长度子串是否为回文的条件,给出状态转移方程。还阐述了动态规划问题的求解思路,包括分解子问题、定状态、确定初始状态值和状态转移方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 的最大长度为1000。

动态规划

代码:

    //动态规划
    public static String longestPalindrome(String s) {
        final int length = s.length();
        int maxLength = 0;
        int start = 0;
        boolean[][] P = new boolean [length][length];
        if (s.length() == 0){
            return "";
        }
        for (int i = 0; i < length; i++){
            P[i][i] = true;
            if (i < length - 1 && s.charAt(i) == s.charAt(i + 1)){
                P[i][i+1] = true;
                start = i;
                maxLength = 2;
            }
        }
        for (int len = 3 ; len <= length ;len ++){ //字串长度
            for (int i = 0 ; i <= length - len; i++){
                /**
                 * 子串结束地址
                 */
                int j=i+len-1;
                if(P[i+1][j-1]&&s.charAt(i)==s.charAt(j))
                {
                    P[i][j]=true;
                    maxLength=len;
                    start=i;
                }
            }
        }
        if (start == 0 && maxLength == 0){
            return s.charAt(s.length() - 1)+"";
        }else if(maxLength >= 2) {
            return s.substring(start, start + maxLength);
        }
        return null;
    }

分析:

假设s = "abbba"

长度为1的子串本身就是回文字符串:

 abbba
atrue    
b true   
b  true  
b   true 
a    true

长度为2的子串有:ab bb bb ba

 abbba
atruefalse   
b truetrue  
b  truetrue 
b   truefalse
a    true

那么长度为3的子串中,是回文字符串的充要条件就是首位字符相等,中间字符为回文字符串。

那么状态转移方程为:P[i+1][j-1]&&s.charAt(i)==s.charAt(j)

for (int i = 0 ; i <= length - 3; i++){
    /**
        * 子串结束地址
        */
    int j=i+len-1;
    if(P[i+1][j-1]&&s.charAt(i)==s.charAt(j))
    {
        P[i][j]=true;
        maxLength=len;
        start=i;
    }
}

长度为3的子串有:abb、bbb、bba

S【0,2】是否是回文字符串需要判断S【1,1】

S【1,3】是否是回文字符串需要判断S【2,2】

S【2,4】是否是回文字符串需要判断S【3,3】

 abbba
atruefalsefalse  
b truetruetrue 
b  truetruefalse
b   truefalse
a    true

长度为4的子串有:abbb、bbba

S【0,3】是否是回文字符串需要判断S【1,2】

S【1,4】是否是回文字符串需要判断S【2,3】

 abbba
atruefalsefalsefalse 
b truetruetruefalse
b  truetruefalse
b   truefalse
a    true

长度为5的子串有:abbba

S【0,4】是否是回文字符串需要判断S【1,3】

 abbba
atruefalsefalsefalsetrue
b truetruetruefalse
b  truetruefalse
b   truefalse
a    true

动态规划问题求解思路

1. 将原问题分解为子问题

    把原问题分解为若干个子问题,子问题和原问题形式相同或类似,只不过规模变小了。子问题都解决,原问题即解决(数字三角形例)。
    子问题的解一旦求出就会被保存,所以每个子问题只需求 解一次。
2. 定状态

    在用动态规划解题时,我们往往将和子问题相关的各个变量的一组取值,称之为一个“状 态”。一个“状态”对应于一个或多个子问题, 所谓某个“状态”下的“值”,就是这个“状 态”所对应的子问题的解。
    所有“状态”的集合,构成问题的“状态空间”。“状态空间”的大小,与用动态规划解决问题的时间复杂度直接相关。 在本例中一共有(1+N)*N/2个子串,所以这个问题的状态空间里一共就有(1+N)*N/2个状态。
    整个问题的时间复杂度是状态数目乘以计算每个状态所需时间。

3. 确定一些初始状态(边界状态)的值

    以“求最长回文字串”为例,初始状态就是字串长度为1,然后长度为2 ……。

4. 确定状态转移方程

     定义出什么是“状态”,以及在该“状态”下的“值”后,就要找出不同的状态之间如何迁移――即如何从一个或多个“值”已知的 “状态”,求出另一个“状态”的“值”(递推型)。状态的迁移可以用递推公式表示,此递推公式也可被称作“状态转移方程”。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值