5. 最长回文子串 - 动态规划(dp)- 力扣(LeetCode)

基础知识要求:

java:方法、字符串、if 语句、for循环、逻辑运算符、二维数组

python: 方法、字符串、if  else语句、for循环、逻辑运算符、二维数组

题目:

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

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:

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

示例 2:

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

提示:

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

Java代码示例 :

public class LongestPalindromeSubstring {  
    /**  
     * 找到给定字符串中的最长回文子串  
     *  
     * @param s 输入的字符串  
     * @return 最长的回文子串  
     */  
    public static String longestPalindrome(String s) {  
        if (s == null || s.length() < 1) {  
            return ""; // 如果字符串为空或长度小于1,则返回空字符串  
        }  
  
        int n = s.length();  
        boolean[][] dp = new boolean[n][n]; // 创建一个二维数组来存储子字符串是否是回文的信息  
        int start = 0, end = 0; // 存储最长回文子串的起始和结束索引  
  
        // 遍历所有可能的子字符串  
        for (int right = 0; right < n; right++) {  
            for (int left = 0; left <= right; left++) {  
                // 如果首尾字符相同,并且去掉首尾的子字符串也是回文的(或者子字符串长度小于等于2),则当前子字符串是回文的  
                if (s.charAt(left) == s.charAt(right) && (right - left <= 2 || dp[left + 1][right - 1])) {  
                    dp[left][right] = true; // 更新dp数组  
                    // 如果当前回文子串长度大于之前找到的最长回文子串长度,则更新最长回文子串的起始和结束索引  
                    if (right - left + 1 > end - start) {  
                        start = left;  
                        end = right;  
                    }  
                }  
            }  
        }  
  
        // 从原始字符串中提取最长回文子串并返回  
        return s.substring(start, end + 1);  
    }  
  
    /**  
     * 主方法,用于测试longestPalindrome方法  
     *  
     * @param args 命令行参数  
     */  
    public static void main(String[] args) {  
        String s = "babad";  
        System.out.println(longestPalindrome(s)); // 输出:"bab" 或 "aba"  
  
        s = "cbbd";  
        System.out.println(longestPalindrome(s)); // 输出:"bb"  
    }  
}

这段代码定义了一个longestPalindrome方法,它接受一个字符串s作为输入,并返回最长的回文子串。它首先检查字符串是否为空或长度小于1,如果是,则返回空字符串。然后,它创建一个二维布尔数组dp来存储子字符串是否是回文的信息。数组dp[i][j]表示从索引ij的子字符串是否是回文的。

接下来,代码使用两个嵌套的循环来遍历所有可能的子字符串。对于每个子字符串,它检查首尾字符是否相等,并且去掉首尾字符的子字符串(如果存在)是否也是回文的。如果是,那么当前子字符串就是回文的,并且更新dp[i][j]true。同时,它还检查当前回文子串的长度是否大于之前找到的最长回文子串的长度,并更新最长回文子串的起始和结束索引。

最后,代码使用substring方法从原始字符串中提取最长回文子串,并将其返回。

main方法中,我们提供了两个示例字符串来测试longestPalindrome方法,并打印出结果。

Python代码示例:

def longestPalindrome(s: str) -> str:  
    n = len(s)  
    if n < 2:  
        return s  
      
    # 初始化动态规划数组  
    # dp[i][j] 表示 s[i:j+1] 是否是回文串  
    dp = [[False] * n for _ in range(n)]  
    # 初始化单个字符都是回文串  
    for i in range(n):  
        dp[i][i] = True  
      
    # 最长回文子串的起始和结束索引  
    start, end = 0, 0  
      
    # 从子串长度为2开始检查回文串  
    for length in range(2, n + 1):  
        # 遍历所有长度为 length 的子串  
        for i in range(n - length + 1):  
            j = i + length - 1  
            # 当子串长度为2时,比较两个字符是否相同  
            if length == 2:  
                dp[i][j] = s[i] == s[j]  
            else:  
                # 如果首尾字符相同,并且去掉首尾的子串也是回文串,则当前子串是回文串  
                dp[i][j] = s[i] == s[j] and dp[i + 1][j - 1]  
              
            # 更新最长回文子串的起始和结束索引  
            if dp[i][j] and j - i + 1 > end - start:  
                start, end = i, j  
      
    # 返回最长回文子串  
    return s[start:end + 1]  
  
# 示例  
s = "babad"  
print(longestPalindrome(s))  # 输出: "bab" 或 "aba"  
  
s = "cbbd"  
print(longestPalindrome(s))  # 输出: "bb"

这段代码首先初始化了一个二维数组 dp 来存储回文子串的信息,然后通过两层循环遍历所有可能的子串,判断它们是否是回文的,并更新最长回文子串的起始和结束索引。最后返回最长回文子串。

值得注意的是,上述代码返回的是最长回文子串的其中一个解,因为可能存在多个最长回文子串。例如,对于输入 "babad",返回 "bab" 或 "aba" 都是正确的。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千小凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值