93.最长回文子串

给你一个字符串 s,找到 s 中最长的 回文 子串。

示例1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例2:

输入:s = "cbbd"
输出:"bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

代码:

class Solution {
    /**
     * 查找字符串中的最长回文子串
     * 使用动态规划方法:
     * 1. dp[i][j] 表示子串 s[i..j] 是否是回文串
     * 2. 先初始化所有长度为1和2的子串的回文状态
     * 3. 然后逐步扩展检查更长的子串
     * 
     * @param s 输入字符串
     * @return 找到的最长回文子串
     */
    public String longestPalindrome(String s) {
        //处理空字符串或长度为0的情况
        if(s==null||s.length()==0)return "";
        //n为字符串s的长度
        int n = s.length();
        //maxLen:记录最长回文子串的长度
        //start:记录最长回文子串的起始位置
        int maxLen = 1,start = 0;
        //dp[i][j] 表示s的子串[i..j]是否是回文
        boolean[][] dp = new boolean[n][n];
        //情况1:所有长度为1的子串都是回文
        for(int i = 0;i<n;i++)dp[i][i] = true;
        //情况2:检查长度为2的子串
        for(int i = 0;i<n-1;i++){
            if(s.charAt(i)==s.charAt(i+1)){
                dp[i][i+1]=true;
                //更新最大长度
                maxLen = 2;
                //更新起始位置
                start = i;
            }
        }
        //情况3:检查长度大于2的子串(从长度3开始)
        for(int len = 3;len<=n;len++){
            //l是子串起始位置
            for(int l = 0;l<=n-len;l++){
                //r是子串结束位置
                int r = l+len-1;
                //状态转移方程:
                //首尾字符必须相同
                //去掉首尾后的子串必须是回文
                if(s.charAt(l)==s.charAt(r)&&dp[l+1][r-1]){
                    dp[l][r] = true;
                    //发现更长的回文子串,更新记录
                    if(len>maxLen){
                        maxLen = len;
                        start = l;
                    }
                }
            }
        }
        //根据记录的起始位置和长度返回子串
        return s.substring(start,start+maxLen);
    }
}
posted @ 2025-05-09 20:57  回忆、少年  阅读(8)  评论(0)    收藏  举报