5. Longest Palindromic Substring

本文探讨了在给定字符串中查找最长回文子串的三种算法:暴力解法、递推解法和动态规划解法。介绍了每种方法的实现思路及时间复杂度,并提供了Python代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:
Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.

Example 2:
Input: “cbbd”
Output: “bb”
题意: 给出一个字符串,求出这个字符串的最长回文子序列
思路1: 暴力解法
直接列出该字符串的所有子串,然后对每一个子串进行判断是否为回文子串,选出最长的回文子串即可,此方法列出所有子串的时间复杂度为O(n2)O(n^2)O(n2),对子串进行判断的时间复杂度是O(n)O(n)O(n),因为两个过程是嵌套关系,因此,暴力解法的整体时间复杂度是O(n3)O(n^3)O(n3).

思路2: 递推解法,对字符串进行遍历,然后对每一个字符考虑对外扩张,判断扩张的字符串是否为回文字符串,考虑两种情况,一种是回文子串长度为奇数,即以某一个字符为中心,两边字符对称,另一种情况为回文子串长度为偶数,处于完全对称的情况。整体为两个循环嵌套,时间复杂度为O(n2)O(n^2)O(n2)
代码仅供参考:

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        n = len(s)
        maxlength1 = 0
        maxlength2 = 0
        start1 = 0
        start2 = 0
        for i in range(n):
            #回文子序列长度为奇数
            j = 0
            length = 0
            while(i>=j and i+j<n):
                if s[i-j] == s[i+j]:
                    length += 1
                    j += 1
                    if length > maxlength1:
                        maxlength1 = length
        #                 print(maxlength1)
                        start1 = i
        #                 print(start1)
                else:
                    break
            #回文子序列长度为偶数
            length = 0
            j = 0
            while(i>=j and i+j<n-1):
                if s[i-j] == s[i+j+1]:
                    length += 1
                    j += 1
                    if length > maxlength2:
                        maxlength2 = length
        #                 print(maxlength2)
                        start2 = i
        #                 print(start2)
                else:
                    break
        if maxlength1 > maxlength2:
            return s[start1-maxlength1+1:start1+maxlength1]
        else:
            return s[start2-maxlength2+1:start2+maxlength2+1]

思路3: 动态规划求解
对于任意字符串,如果头尾字符相同,那么字符串的最长子序列等于去掉首尾的字符串的最长子序列加上首尾;如果首尾字符不同,则最长子序列等于去掉头的字符串的最长子序列和去掉尾的字符串的最长子序列的较大者。

因此动态规划的状态转移方程为:

设字符串为str,长度为n,p[i][j]n,p[i][j]np[i][j]表示第i到第j个字符间的子序列的个数(i&lt;=j)(i&lt;=j)i<=j,则:

状态初始条件:dp[i][i]=1(i=0:n−1)dp[i][i]=1 (i=0:n-1)dp[i][i]=1i=0n1

状态转移方程:dp[i][j]=dp[i+1][j−1]+2if(str[i]==str[j])dp[i][j]=dp[i+1][j-1] + 2 if(str[i]==str[j])dp[i][j]=dp[i+1][j1]+2ifstr[i]==str[j]
       dp[i][j]=max(dp[i+1][j],dp[i][j−1])if(str[i]!=str[j])dp[i][j]=max(dp[i+1][j],dp[i][j-1]) if (str[i]!=str[j])dp[i][j]=max(dp[i+1][j],dp[i][j1])ifstr[i]!=str[j]
时间复杂度为O(n2)O(n^2)O(n2)
代码仅供参考:

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        #动态规划的方法求取
        n = len(s)
        matrixmark = [[0 for i in range(n)] for i in range(n)] #创建一个nxn的矩阵,记录s[i] = s[j]的情况
        maxlen = 0
        maxstr = ''
        for i in range(n):
            for j in range(i+1):
                if i-j <= 1 and s[i] == s[j]:
                    matrixmark[i][j] = 1
                    if i-j+1 > maxlen:
                        maxlen = i-j+1
                        maxstr = s[j:i+1]
                elif s[i] == s[j] and matrixmark[i-1][j+1] == 1:
                    matrixmark[i][j] = 1
                    if i-j+1 > maxlen:
                        maxlen = i-j+1
                        maxstr = s[j:i+1]
        return maxstr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值