最长回文子串(dp解法)

题目大意

题目传送门:https://leetcode-cn.com/problems/longest-palindromic-substring/
给你一个字符串,寻找其中最长回文子串并输出。

DP解法

首先对题目进行分析,这个最长的回文子串有什么特点?对于字符串str,假设dp[i,j]=1表示str[i…j]是回文子串,那个必定存在dp[i+1,j-1]=1。这样最长回文子串就能分解成一系列子问题,可以利用动态规划求解了。首先构造状态转移方程:
在这里插入图片描述
则整个方程的初始状态应该是这样的:
在这里插入图片描述
意思就是单个字符一定是一个回文串,连续两个相邻的相等字符也一定是回文串,比如“aa”。
这样就可以写出代码:

class Solution {
public:
        string longestPalindrome(string s) {
        if (s.empty()) return "";
        int len = s.size();
        if (len == 1)return s;
        int longest = 1;
        int start=0;
        int dp[1005][1005] = {0};
        for(int i = 0;i<len;i++)
        {
            dp[i][i] = 1;
            if(i<len-1)
            {
                if(s[i]==s[i+1])
                {
                    dp[i][i+1] = 1;
                    start = i;
                    longest = 2;
                }
            }
        }
        for(int l = 3;l<=len;l++)//子串的长度,范围是从3到len
        {
            for(int i = 0;i+l-1<len;i++)
            {
                int j = i+l-1;//终点
                if(s[i]==s[j] && dp[i+1][j-1]==1)
                {
                    dp[i][j] = 1;
                    start = i;
                    longest = l;
                }
            }
        }
        return s.substr(start,longest);
    }
};

另一种解法(Manacher)

一种专门用来解决此类问题的算法叫做“马拉车算法”,总体思想是“中心扩展”,由于回文子串的特性,遍历整个字符串,分别以每个字符作为对称轴向两边进行扩展,直至找到最长的回文子串。但是要注意回文子串长度为奇数和偶数的处理方法不太一样,具体的解释请参考:https://www.cxyxiaowu.com/2869.html中的方法三

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最长回文子串的问题可以使用不同的方法来解决。引用中的代码使用了暴力解法,即遍历字符串的所有子串,并判断是否是回文串,然后找出最长的回文子串。该方法的时间复杂度为O(n^3)。 引用中的方法使用了动态规划的思想,通过递推关系来求解最长回文子串。该方法的时间复杂度为O(n^2)。动态规划的状态转移方程为:dp[i][j表示字符串s从索引i到索引j是否是回文串,如果s[i等于s[j且dp[i+1][j-1为True,则dp[i][j也为True。 下面是一个使用动态规划的Python实现: ``` class Solution: def longestPalindrome(self, s): n = len(s) if n < 2: return s max_len = 1 begin = 0 # dp[i][j表示s[i..j是否是回文串 dp = [[False * n for _ in range(n)] for i in range(n): dp[i][i = True # 递推开始 for L in range(2, n+1): for i in range(n): j = L + i - 1 if j >= n: break if s[i != s[j]: dp[i][j = False else: if j - i < 3: dp[i][j = True else: dp[i][j = dp[i+1][j-1] if dp[i][j and j - i + 1 > max_len: max_len = j - i + 1 begin = i return s<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Python最长回文子串](https://blog.csdn.net/weixin_42698464/article/details/121389797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值