005最长回文子串

写在前面,参考的力扣官网的题解,动态规划

一、java代码

/*
 * @lc app=leetcode.cn id=5 lang=java
 *
 * [5] 最长回文子串
 */

// @lc code=start





class Solution {
    public String longestPalindrome(String s) {

        //特殊的判断,获得字符串长度
        int len=s.length();

        //如果长度小于2,则直接返回字符串
        if(len<2){
            return s;
        }

        //定义最长回文子串长度,起始位置
        int maxLen=1;
        int begin=0;

        //dp[i][j]表示s[i..j]是否是回文串
        boolean[][]dp=new boolean[len][len];

        //字符本身是回文子串,所以先把对角线的定义出来
        for(int i=0;i<len;i++){
            dp[i][i]=true;
        }

        //将字符串对象中的字符转换为一个字符数组
        char[] charArray=s.toCharArray();

        //先升序填列
        for(int j=1;j<len;j++){
            //再升序填行
            for(int i=0;i<j;i++){

                //dp[i][j]=(s[i]==s[j]) and (j-i<3 or dp[i+1][j-1])
                //首先改子串的起始位置的字符应该相等
                //再看(尾-头)=0,1,2即<3时直接为true;
                //若>=3,则转成子问题,看dp[i+1][j-1]
                if(charArray[i]!=charArray[j]){
                    dp[i][j]=false;
                }else{
                    if(j-i<3){
                        dp[i][j]=true;
                    }else{
                        dp[i][j]=dp[i+1][j-1];
                    }
                }
                //若改子串为回文串,则判断是否为最长
                if(dp[i][j]&&j-i+1>maxLen){
                    maxLen=j-i+1;
                    begin=i;
                }
            }
        }
        //截取子串substring(int beginIndex, int endIndex)
        return s.substring(begin,begin+maxLen);

    }
}
// @lc code=end


二、动态规划分析

1、状态

dp[i][j]表示子串s[i..j]是否为回文子串

2、得到状态转移方程

dp[i][j]=(s[i]==s[j]) and dp[i+1][j-1]

--边界条件 :j-1-(i+1)+1<2整理得j-i<3

3、初始化

dp[i][i]=true

4、输出

在得到一个状态的值为true的时候,记录起始位置和长度,填表完成后截取

三、图解


写在后面:在写这道题的时候把动态规划又认真看了一遍,这两篇博文写的都很好,贴在下面
b站视频整理
知识点的整理

原文地址:https://www.cnblogs.com/lxr-xiaorong/p/13444865.html