LeetCode-Golang之【5. 最长回文子串】

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

示例 1:

输入: "babad"

输出: "bab"

注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"

输出: "bb"

本算法采用 动态规划去解析

复制代码
func longestPalindrome(s string) string {
    n :=len(s)
    dp :=make([][]int,n)
    for i:=0;i<n;i++{
        dp[i] = make([]int,n)
    }
    
    ans := ""
    for k:=0;k<n;k++{
        for i:=0;i+k<n;i++{
            j:=i+k
            if k == 0 {
                dp[i][j] = 1
            }else if k == 1 {
                if s[i] == s[j] {
                    dp[i][j] = 1
                }
            }else {
                if s[i] == s[j] {
                    dp[i][j] = dp[i+1][j-1]
                }   
            }
            if dp[i][j] == 1 && k+1 > len(ans){
                ans = s[i:j+1]
            }
        }
    }
    return ans
}

代码解析:

  1. 初始化二维 DP 表格

    n := len(s)
    dp := make([][]int, n)
    for i := 0; i < n; i++ {
    dp[i] = make([]int, n)
    }

功能:

dpij 表示子串 si:j+1 是否是回文子串。值为 1 表示是回文,0 表示不是。

初始化一个大小为 n × n 的二维数组 dp,用于存储所有子串的回文状态。

  1. 遍历子串长度 k(主循环)

    for k := 0; k < n; k++ {
    for i := 0; i+k < n; i++ {
    j := i + k
    ...
    }
    }

功能:

遍历所有可能的子串长度 k(k+1 是实际长度)。

i 是子串的起始位置,j = i + k 是子串的结束位置。

子串的范围是 si:j+1

  1. 判断子串是否是回文

    if k == 0 {
    dp[i][j] = 1
    } else if k == 1 {
    if s[i] == s[j] {
    dp[i][j] = 1
    }
    } else {
    if s[i] == s[j] {
    dp[i][j] = dp[i+1][j-1]
    }
    }

功能:

根据子串长度的不同情况,判断是否为回文:

长度为 1(k == 0):

单个字符总是回文,直接标记为 1。

长度为 2(k == 1):

如果两个字符相等,则是回文。

长度大于 2(k > 1):

首尾字符相等,且去掉首尾的子串 si+1:j 也为回文(通过 dpi+1j-1 判断)。

  1. 更新答案

    if dp[i][j] == 1 && k+1 > len(ans) {
    ans = s[i : j+1]
    }

功能:

如果当前子串 si:j+1 是回文且长度超过当前记录的最长回文,则更新答案 ans。

k+1 是子串的实际长度。

完整运行流程示例

假设输入字符串为 s = "babad":

初始化 dp 矩阵为全 0,ans = ""。

遍历所有可能的子串:

子串长度 k = 0:

每个单字符都是回文,如 dp00 = 1,dp11 = 1。

子串长度 k = 1:

检查相邻字符是否相等。如 s0:2 = "ba" 不是回文,但 s1:3 = "aba" 是回文。

子串长度 k = 2:

检查三字符回文,通过 dpi+1j-1 判断。

每次找到更长的回文时,更新答案。

最终结果为 "bab" 或 "aba"。

复杂度分析

时间复杂度:O(n²)

遍历子串的起点 i 和长度 k。

空间复杂度:O(n²)

使用了一个二维数组 dp 存储状态。

相关推荐
圣保罗的大教堂4 小时前
leetcode 3867. 数对的最大公约数之和 中等
leetcode
To_OC6 小时前
LC 15 三数之和:双指针不难,难的是把去重做对
javascript·算法·leetcode
renhongxia19 小时前
世界模型,是“空中楼阁”还是AGI的“最后一块拼图”?
运维·服务器·数据库·人工智能·算法·agi
G.O.G.O.G9 小时前
LeetCode SQL 从入门到精通(MySQL)06(上)
数据库·sql·mysql·leetcode
zephyr0511 小时前
动态规划-最长上升子序列问题
算法·动态规划
闪电悠米11 小时前
力扣hot100-56.合并区间-排序详解
数据结构·算法·leetcode·贪心算法·排序算法
卡提西亚12 小时前
leetcode-1438. 绝对差不超过限制的最长连续子数组
算法·leetcode·职场和发展
Java面试题总结13 小时前
LeetCode 93.复原IP地址
算法·leetcode·职场和发展·.net
从零开始的代码生活_13 小时前
C++ 多态详解:虚函数、动态绑定、抽象类与虚表原理
开发语言·c++·后端·学习·算法
Tisfy14 小时前
LeetCode 3867.数对的最大公约数之和:按题目说的做(gcd)
算法·leetcode·题解·模拟·最大公约数·gcd