求解最長迴文子串

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

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

  dp,除此之外還有一些很炫的解法,這裏只講dp這是一道很好的入門題。
  我一向認爲dp第一步不是寫狀態轉移方程,而是把狀態設對。涉及到字符串的子串起碼應該想到二維數組dpijdp_{ij},至於這個代表什麼,就是手感了,設的好方程 (猜)的輕鬆,否則基本gg;
  這裏直接給答案,dpijdp_{ij}表示以sisjs_i開頭至以s_j結尾的串.如果si...sjs_i...s_j爲迴文串,那麼si1...sj+1s_{i-1}...s_{j+1}爲迴文串的條件就是si1==sj+1s_{i-1}==s_{j+1}

初始狀態:dp[i][i]==true;           i∈1...n
dp[i][j]=dp[i+1]d[j-1]&&(s[i]==s[j]) 

畫表理解一下,以babad爲例,填的順序是斜着填的

1 0 1 0 0
1 0 1 0
1 0 0
1 0
1

在這裏插入圖片描述上代碼

class Solution {
public:
    string longestPalindrome(string s) {
        int len=s.length();
        vector<vector<bool>> d(len, vector<bool>(len));
        int max=1,p=0,flag=1;
        for(int i=0;i<len;i++)//初始化
            d[i][i]=true;
        for(int j=1;j<len;j++)
        {
            for(int i=0;i<len-j;i++)
            {
                if(j==1)//長度爲2的串
                {
                    d[i][j+i]=(s[i]==s[i+1]);
                    if(d[i][i+1]&&flag)//flag用於只記錄第一個長度爲2的迴文串,不用也沒關係
                    {
                        max=2;
                        p=i;
                        flag=0;
                    }
                }
                else//長度大與2的串
                {
                    d[i][j+i]=d[i+1][i+j-1]&&(s[i]==s[i+j]);//轉移方程
                    if(d[i][j+i]&&j+1>max)
                    {
                        max=j+1;
                        p=i;
                    }
                }
            }
        }
        return s.substr(p, max);//從p開始切割max位
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章