[M]Longest Palindromic Substring最长回文子串

本文介绍了如何使用动态规划解决最长回文子串问题,详细阐述了状态转移方程和边界条件,展示了如何通过Python代码求解,并分析了算法的时间和空间复杂度。关键步骤包括初始化对角线为真,检查子串长度和头尾字符,优化输出结果。
摘要由CSDN通过智能技术生成

题目描述

Given a string s, return the longest palindromic substring in s.
在这里插入图片描述

题解思路

动态规划——状态如何转移
一个回文去掉两头以后,剩下的部分依然是回文

  • 如果一个字符串的头尾不相等,那么这个字符串一定不是回文串;如果一个字符串的头尾两字符相等,才继续判断下去。
  • 如果里面的子串是回文,整体是回文串;如果子串不是回文串,整体就不是回文串。

即需要判断原字符串的一个子串是否为回文子串

1.定义

dp[i][j] 的 True,False表示子串 s[i…j] 是否为回文子串

2.需要满足状态转移方程

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

3.说明

构成子串,因此 i 和 j 的关系是 i <= j
对 dp[i + 1][j - 1] 考虑边界情况:
边界条件是: [i + 1, j - 1] 不构成区间,即长度小于 2,即 j - 1 - (i + 1) + 1 < 2 ,即 j - i < 3。

j - i < 3 ,则区间长度 j - i + 1 < 4,即当子串 s[i…j] 的长度等于 2 或者等于 3 的时候,其实只需要判断一下头尾两个字符是否相等就可以直接下结论了。

  • 如果子串 s[i + 1…j - 1] 只有 1 个字符,即去掉两头,剩下中间部分只有 11 个字符,显然是回文;
  • 如果子串 s[i + 1…j - 1] 为空串,那么子串 s[i, j] 一定是回文子串。
    因此在 s[i] == s[j] 和 j - i < 3 的前提下,直接得dp[i][j] = true,不满足上述条件才执行状态转移。

参考思路from这里的题解

4.初始化和输出什么

(可省略)初始化:单个字符一定是回文串,因此把对角线先初始化为 true,即 dp[i][i] = true 。
输出:只要一得到 dp[i][j] = true,就记录子串的长度起始位置,没有必要截取消耗性能,记录此时的回文子串的「起始位置start」和「回文长度max_length」即可。

python代码

class Solution:
    def longestPalindrome(self, s: str) -> str:
        length=len(s)
        dp=[[False]*length for _ in range(length)]
        start=0
        max_length=1
        for i in range(length):
            dp[i][i]=True
        if length<2:
            return s
        for j in range(1,length):
            for i in range(0,j):
                if s[i]==s[j]:
                    if j-i<3:
                        dp[i][j]=True
                    else:
                        dp[i][j]=dp[i+1][j-1]
                else:
                    dp[i][j]=False
                if dp[i][j]:
                    cur_length=j-i+1
                    if cur_length>max_length:
                        max_length=cur_length
                        start=i
        return s[start:start+max_length]

复杂度

时间复杂度: O ( N 2 ) O(N^2) O(N2)
空间复杂度: O ( N 2 ) O(N^2) O(N2)

—2020/10/16太弱以至于理解费劲优化无能QAQ----

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值