leetcode 5 用動態規劃方法找字符串中最長迴文子串

給定一個字符串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度爲 1000。

示例 1:

輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。

假設字符串s的長度爲length,建立一個length*length的矩陣dp。

dp[i][j]表示“以s[i]開始s[j]結尾的迴文串的長度。如果這個字符串不是迴文串,讓dp[i][j]=true”。顯然,j>=i,只需往dp填j>=i的部分即可。

dp[i][j]的遞推公式可以這麼表述:

(1)首先對dp的對角線元素初始化爲1,也就是當i==j時,dp[i][j]=true。

這很顯然,每個單獨的字符其實就是個長度爲1的迴文串。

(2)當j-i==1:

若s[i]==s[j],則dp[i][j]=true;

解釋:當j-i==1時,若s[i]==s[j],則s[i]和s[j]可以組成一個長度爲2的迴文串。若s[i]!=s[j],顯然他們不可能組成迴文串,dp[i][j]=0。

(3)當j-i>=2:

若s[i]==s[j]:若dp[i+1][j-1] = true,則dp[i][j]= true,否則dp[i][j] = false;

若s[i]!=s[j]:dp[i][j] = false;

解釋:如果s[i]==s[j],表明這個子串有可能是迴文串。當去頭去尾後它是迴文串時,就可以認爲這和個子串是迴文串,得到它的長度。如果去頭去尾後不是迴文串,那這個子串一定不是迴文串,迴文串長度只能是0。

若s[i]!=s[j],顯然他們不可能組成迴文串,dp[i][j]=false。

當dp[i][j]爲迴文串則判斷其是否比當前最大回文串長度大。若大於則記錄起始下標和子串長度
 

class Solution {
public:
    string longestPalindrome(string s) {
        int start = 0, maxLen = 1, n = s.size();
        vector<vector<bool> >dp(n , vector<bool>(n,false));
        for(int i=n-1; i>=0; i--) {
            for(int j=i; j<n; j++) {
                if(( i + 1 > j -1 || dp[i+1][j-1]) && s[i]==s[j]) {
                    dp[i][j] = true;
                    if(j-i+1>maxLen) {
                        maxLen = j-i+1;
                        start = i;
                    }
                }
            }
        }
        return s.substr(start,maxLen);
    }
};
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章