1. 程式人生 > >leetcode 5.最長迴文子串

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);
}


未完待續