給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: 「babad」
輸出: 「bab」
注意: 「aba」 也是乙個有效答案。
示例 2:
輸入: 「cbbd」
輸出: 「bb」
這道題比較煩人的是判斷回文子串。因此需要一種能夠快速判斷原字串的所有子串是否是回文子串的方法,於是想到了「動態規劃」。
「動態規劃」的乙個關鍵的步驟是想清楚「狀態如何轉移」。事實上,「回文」天然具有「狀態轉移」性質。
乙個回文去掉兩頭以後,剩下的部分依然是回文(這裡暫不討論邊界情況);
依然從回文串的定義展開討論:
如果乙個字串的頭尾兩個字元都不相等,那麼這個字串一定不是回文串;
如果乙個字串的頭尾兩個字元相等,才有必要繼續判斷下去。
如果裡面的子串是回文,整體就是回文串;
如果裡面的子串不是回文串,整體就不是回文串。
即:在頭尾字元相等的情況下,裡面子串的回文性質據定了整個子串的回文性質,這就是狀態轉移。因此可以把「狀態」定義為原字串的乙個子串是否為回文子串。
第 1 步:定義狀態
dp[i][j] 表示子串 s[i…j] 是否為回文子串,這裡子串 s[i…j] 定義為左閉右閉區間,可以取到 s[i] 和 s[j]。
第 2 步:思考狀態轉移方程
在這一步分類討論(根據頭尾字元是否相等),根據上面的分析得到:
dp[i][j] = (s[i] == s[j]) and dp[i + 1][j - 1]
說明:「動態規劃」事實上是在填一張二維**,由於構成子串,因此 i 和 j 的關係是 i <= j ,因此,只需要填這張**對角線以上的部分。
看到 dp[i + 1][j - 1] 就得考慮邊界情況。
這個結論很顯然:j - i < 3 等價於 j - i + 1 < 4,即當子串 s[i…j] 的長度等於 2 或者等於 3 的時候,其實只需要判斷一下頭尾兩個字元是否相等就可以直接下結論了。
如果子串 s[i + 1…j - 1] 只有 1 個字元,即去掉兩頭,剩下中間部分只有 11 個字元,顯然是回文;
如果子串 s[i + 1…j - 1] 為空串,那麼子串 s[i, j] 一定是回文子串。
因此,在 s[i] == s[j] 成立和 j - i < 3 的前提下,直接可以下結論,dp[i][j] = true,否則才執行狀態轉移。
第 3 步:考慮初始化
初始化的時候,單個字元一定是回文串,因此把對角線先初始化為 true,即 dp[i][i] = true 。
事實上,初始化的部分都可以省去。因為只有乙個字元的時候一定是回文,dp[i][i] 根本不會被其它狀態值所參考。
第 4 步:考慮輸出
只要一得到 dp[i][j] = true,就記錄子串的長度和起始位置,沒有必要擷取,這是因為擷取字串也要消耗效能,記錄此時的回文子串的「起始位置」和「回文長度」即可。
大家能夠可以自己動手,畫一下**,相信會對「動態規劃」作為一種「**法」有乙個更好的理解。
package org.lzh.testleetcode;
public
class
longestpalindromicsubstring
int maxheadindex=0;
int maxtailindex=0;
int maxlength=1;
char
chararray=s.
tochararray()
;for
(int j=
1;jlength()
;j++
)else
else}if
(ishuiwen[i]
[j]&& j - i +
1> maxlength)}}
//
// for(int j=1;j// for(int i=j;i
// if (ishuiwen[i][j]==true)
// }
//
// }
return s.
substring
(maxheadindex, maxtailindex+1)
;}public
static
boolean
ishuiwen
(string a,
int i,
int j)
result =a.
charat
(i++
)==a.
charat
(j--);
}return result;
}}
最長回文串 演算法 4 求解最長回文子串
問題描述 給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。注釋 回文通俗的說就是正著念和反著念都一樣,如 上海自來水來自海上。示例 1 輸入 dabccbac 輸出 abccba 示例 2 輸入 cbbd 輸出 bb 解題思路 此處撰寫解題思路 遍歷每乙個索引,...
最長回文子串 最長回文子串行
1.最長回文子串行 可以不連續 include include include include using namespace std 遞迴方法,求解最長回文子串行 intlps char str,int i,int j intmain include include include using n...
最長回文子串
描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘的字串 輸入字串長度大於等於1小於等於5000,且單獨佔一行 如果...