5. 最长回文子串

5. 最长回文子串

原始题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/

给你一个字符串 s,找到 s 中最长的回文子串。
在这里插入图片描述
在这里插入图片描述

解题思路:

使用动态规划思路解题。定义状态dp[i][j]表示字符串s的子串s[i: j + 1](字符串第i个字符到第j个字符的闭区间的子串)是否是回文串,所以初始化动态方程数组dp[][]的值使用布尔运算符False,特别地对角线表示i和j是相等的,即单个字符,肯定是回文,所以初始化的时候赋值为True。当前状态需要判断首尾两个字符是否相等:s[i] == s[j],过去状态dp[i + 1][j - 1],就是前后各缩减一个字符,如果当前状态的首付两个字符都相等并且过去状态是回文串,那当前状态肯定也是回文串即d[i][j]为True。考虑边界条件,当右边索引小于左边索引的时候,即j - 1 -(i + 1)<= 0时,等价于j - i <= 2,如下图的对角线左下方的情况,从图中可以看出对角线满足s[i] == s[j],左下方的情况继续判断s[i] == s[j]的情况,满足就是回文串。对角线右上方的情况,根据当前状态和过去状态来判断是否为回文串。每次判断完更新开始索引和最大长度的值。具体实现看代码及注释。以s=“babab”为例子的状态图:

在这里插入图片描述

代码实现:

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)

        # 字符串小于2,单个或空字符,返回s即可
        if n < 2:
            return s
        
        # dp[i][j]表示s[i:j+1]是否是回文串
        # 初始化dp数组,对角线i=j,s[i:j+1]表示相同的字符肯定是回文串,则为True
        dp = [[False]*n for _ in range(n)]
        for i in range(n):
            dp[i][i] = True
        
        # 初始化最大回文字符串的开始和结束索引为1和0
        # 这样s[begin_index, begin_index + max_index]就表示第一个字符
        max_index, begin_index = 1, 0

        # 开始遍历s,分为边界条件和非边界条件
        for j in range(1, n):
            for i in range(j):
                # 边界条件:j-1 - (i + 1) <= 0,即j - i <= 2
                if j - i <= 2:
                    # 只需要判断s[i]是否等于s[j]
                    if s[i] == s[j]:
                        dp[i][j] = True
                        # 记录当前子串的长度
                        cur_len = j - i + 1
                
                # 非边界条件,就要判断首尾字符是否相等和上一个状态是否是回文串
                else: 
                    if s[i] == s[j] and dp[i + 1][j - 1] :
                        dp[i][j] = True
                        cur_len = j - i + 1
            
                if dp[i][j]:
                    if cur_len > max_index:
                        max_index = cur_len
                        begin_index = i
        
        return s[begin_index: begin_index + max_index]

参考文献:
https://leetcode-cn.com/problems/longest-palindromic-substring/solution/5-zui-chang-hui-wen-zi-chuan-dong-tai-gu-p7uk/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值