最長回文字串

2022-03-07 17:15:27 字數 1559 閱讀 9947

leetcode中有這麼一道題:

給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為1000。

示例 1:

輸入: "babad"

輸出: "bab"

注意: "aba"也是乙個有效答案。

示例 2:

輸入: "cbbd"

輸出: "bb"

回文串的定義我就不囉嗦了。對於這道題,我的第一反應是用動態規劃方法解。

假設字串s的長度為length,建立乙個length*length的矩陣dp。

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

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

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

這很顯然,每個單獨的字元其實就是個長度為1的回文串。

(2)當j-i==1:

若s[i]==s[j],則dp[i][j]=2;否則dp[i][j]=0。

解釋:當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]>0,則dp[i][j]= dp[i + 1][j - 1] + 2;否則dp[i][j]= 0;

若s[i]!=s[j]:dp[i][j]=0。

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

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

只需找到dp[i][j]的最大元素和它對應的i和j就可以得到結果「s中最長回文子串」。

另外還有乙個要注意的點:因為需要訪問dp[i+1][j-1],因此i是從大到小的,j是從小到大的。j從0到size-1,i從j-1到0。

貼上我的c++**:

1 classsolution 

16 }

17 int start = 0, max = 1;

18 for (int j = 0; j < size;j++)

26 else dp[i][j] = 0;

27 }

28 }

29 else dp[i][j] = 0;

30 if (dp[i][j]>max)

33 }

34 }

35 returns.substr(start, max);

36 }

37 };

時間複雜度和空間複雜度都為o(n^2),n為字串長度。

介紹了manacher'salgorithm——馬拉車演算法,可以在o(n)時間複雜度得到最長回文串。

最長回文字串

scanf s 輸入字串碰到空格或者tab就會停下來。此處可以使用fgets或者gets 另外注意標頭檔案cctype中的函式的巧妙使用,此處使用isalpha和toupper簡化了 此處列舉字串的中間位置,然後向倆邊擴充套件,節省了時間複雜度,注意向倆邊擴充套件時,奇數個和偶數個長度的區別。另外程...

最長回文字串

回文串定義 回文串 是乙個正讀和反讀都一樣的字串,比如 asddsa 或者 lovekevol 等等就是回文串。回文子串,顧名思義,即字串中滿足回文性質的子串。這裡我給出通過 列舉回文串的中間位置i,然後不斷向外擴充套件,直達有字元不相同。注意,這裡長度為奇數和偶數的處理方式是不一樣的。下面給出 這...

最長回文字串

時間限制 1000 ms 記憶體限制 65535 kb 難度 4 描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘...