最长回文子串

题目

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:

输入: "cbbd"
输出: "bb"

回文的定义

正读和反读都相同的字符序列为“回文”,如“abba”、“abccba”是“回文”,“abcde”和“ababab”则不是“回文”。字符串的最长回文子串,是指一个字符串中包含的最长的回文子串。例如“1212134”的最长回文子串是“12121”。

思路

此题暴力方法时间复杂度为O(n^3),采用两个循环遍历得到所有子串,然后再用一个循环判断每个子串是否是回文子串。不过这里还是采用容易想到的动态规划方法。首先定义 dp[i][j] 为,判断 S[i,j] 区间内的字符串是不是回文子串,其中ij表示子串在s中的左右位置;接下来我们解析动态规划方法的状态转移方程,如果 S[i,j] 是回文子串,当且仅当S[i] == S[j]&&dp(i+1,j-1)==1满足, 其中 i+1<=j-1,即j-i>=2; 当然还有一种情况,j-i<2, 也就是一字母和二字母的回文,二字母的回文仅仅需要S[i] == S[j] 即可,一字母本身就是回文。以上可以列状态方程:

\dpi{120} dp(i,j)=\begin{cases} true& \text{(S[i] == S[j] and dp(i+1,j-1))==1)}\\ false& \text{Others} \end{cases}$$

由此时间复杂度O(n^2),空间复杂度O(n^2)。

string getLongestPalindrome(string str, int n) { // n为字符串的长度
    if (n <= 1) return str; 
    vector<vector<int>> dp(n, vector<int>(n, 0));
    int start = 0;      //回文串起始位置
    int maxlen = 1;     //回文串最大长度
    for (int j = 0; j<n; j++){
        dp[j][j] = 1;  //初始化一字母回文串
        for (int i = 0; i<j; i++){
            //当满足(str[i] == str[j] && j-i<2) 则为初始化两字母回文串
            //当满足(str[i] == str[j] && dp[i + 1][j - 1] == 1)
            if (str[i] == str[j] && (j - i<2 || dp[i + 1][j - 1] == 1)){
                dp[i][j] = 1;
                if (maxlen < j-i+1) 
                {
                    start = i;   // 更新回文串长度和位置
                    maxlen = j - i + 1;
                }
            }
        }
    }
    return str.substr(start,maxlen);
}

参考:https://blog.csdn.net/u013309870/article/details/70742315

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值