返回

动态规划巧解 LeetCode 5:最长回文子串

见解分享

LeetCode 5. 最长回文子串:揭秘查找完美对称

前言

踏上 LeetCode 算法征程的各位勇士,我们今天将目光投向第 5 道难题,一个看似简单实则暗藏玄机的挑战——最长回文子串。我们该如何巧妙地挖掘字符串中的回文奥秘,从中找出最长的回文子串呢?准备好迎接一场算法思维的盛宴吧!

回顾知识点

在深入探索这道难题之前,让我们先温故而知新,回顾一下前面学习过的相关知识点:

  • 数组 :用于存储元素的集合,支持通过索引访问和修改元素。
  • 哈希表 :一种高效的数据结构,可以快速根据键查找和插入元素。
  • 二叉树 :一种树形结构,每个节点最多有两个子节点。
  • 树的遍历 :访问二叉树中所有节点的方法,包括前序、中序和后序遍历。
  • 二分查找 :一种在排序数组中快速查找元素的算法。
  • 动态规划 :一种自底向上的解决问题的方法,将问题分解成子问题。
  • 贪心算法 :一种基于局部最优选择做出决策的算法。

题目分析

题目
给定一个字符串 s,请找出其中的最长回文子串。回文子串是指正读和反读都相同的子串。

示例:

  • 输入:s = "babad"
  • 输出:"bab"

算法思路

解决这道题,我们可以考虑两种主要算法:

暴力求解法:

  • 生成字符串的所有子串。
  • 检查每个子串是否为回文。
  • 记录最长的回文子串。

动态规划解法:

  • 创建一个 dp 表,其中 dp[i][j] 表示子串 s[i:j+1] 是否为回文。
  • 使用动态规划的思想,根据以下规则填充 dp 表:
    • 如果 i >= j,则 dp[i][j] = True
    • 如果 s[i] = s[j],则 dp[i][j] = dp[i+1][j-1]
    • 否则,dp[i][j] = False
  • dp 表中找到最长的回文子串的长度。

代码实现(动态规划解法)

def longestPalindrome(s):
    n = len(s)
    dp = [[False] * n for _ in range(n)]

    # 初始化对角线元素为 True
    for i in range(n):
        dp[i][i] = True

    # 填充动态规划表
    for i in range(n-1, -1, -1):
        for j in range(i+1, n):
            if s[i] == s[j]:
                if j - i <= 2 or dp[i+1][j-1]:
                    dp[i][j] = True

    # 找到最长回文子串的长度和起点
    max_len = 0
    start = 0
    for i in range(n):
        for j in range(n):
            if dp[i][j] and j - i + 1 > max_len:
                max_len = j - i + 1
                start = i

    # 返回最长回文子串
    return s[start:start+max_len]

总结

LeetCode 5. 最长回文子串是一道经典的算法题,考验着算法思维和代码实现能力。通过采用动态规划的解法,我们可以有效地找出字符串中的最长回文子串,提升算法效率。

继续努力刷题,让 LeetCode 成为你算法技能的试金石,不断突破自我,成为算法大师!