leetcode 5.最长回文子串

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

回文:把相同的词汇或句子 ,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环 。

示例 1:

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

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

1、暴力法

最容易想到的就是暴力破解,求出每一个子串,之后判断是不是回文,找到最长的那个。

求每一个子串时间复杂度O(N^2),判断子串是不是回文O(N),两者是相乘关系,所以时间复杂度为O(N^3)。

class Solution {
public:
    string longestPalindrome(string s) {
        int length = s.size();
        int maxlen = 0;
        int start = 0;
        for(int i = 0; i<length; ++i){
            for(int j=i+1; j<length; ++j){
                int m = 0, n = 0;
                for(m = i, n = j; m < n; ++i, --j){
                    if(s.at(m) != s.at(n))
                        break;
                }
                if(m >= n && j-i > maxlen){
                    maxlen = j=i-1;
                    start = i;
                }
                    
            }
        }
        if(maxlen > 0)
            return s.substr(start, maxlen);
        return NULL;
        
    }
};

2、动态规划

动态规划问题是面试题中的热门话题,如果要求一个问题的最优解(通常是最大值或者最小值),而且该问题能够分解成若干个子问题,并且小问题之间也存在重叠的子问题,则考虑采用动态规划。

使用动态规划特征: 
1. 求一个问题的最优解 
2. 大问题可以分解为子问题,子问题还有重叠的更小的子问题 
3. 整体问题最优解取决于子问题的最优解(状态转移方程) 
4. 从上往下分析问题,从下往上解决问题 
5. 讨论底层的边界问题

回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文字符串,那么P[i+1,j-1]也是回文字符串。这样最长回文子串就能分解成一系列子问题了。这样需要额外的空间O(N^2),算法复杂度也是O(N^2)。

首先定义状态方程和转移方程:

P[i,j]=0表示子串[i,j]不是回文串。P[i,j]=1表示子串[i,j]是回文串。

string longestPalindrome(string s)
{
    if (s.empty()) return "";
    int len = s.size();
    if (len == 1)return s;
    int longest = 1;
    int start=0;
    vector<vector<int> > dp(len,vector<int>(len));
    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++)//子串长度
    {
        for (int i = 0; i+l-1 < len; i++)//枚举子串的起始点
        {
            int j=l+i-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);
}


未完待续

猜你喜欢

转载自blog.csdn.net/qq_36086861/article/details/85055228