タイトル指定された文字列要求は、最も長い最長のサブストリング、特にサブパリンドロームサブストリングである方全てのサブ集合列パリンドローム配列の長さを見つけるために、パリンドローム、力の使用の最初の考えられる方法は、サブストリング長さは、奇数と偶数長の議論、時間Oの複雑さ(N ^ 2)であるが、次のようにleetcodeタイムアウトエラーでこの暴力を解決する方法は、特定のコードが報告されます。
A.暴力行為
参照コード
書式#include < 文字列 > の#include < 文字列の.h> 使用して 名前空間はstdを、 クラス解決{ パブリック: 文字列 longestPalindrome(ストリングS){ 場合(s.empty()|| s.size()<= 1)リターンS。 INTサイズ= s.size()。 ストリング odd_str = longestPalindrome_odd(S、サイズ)。 ストリング even_str = longestPalindrome_even(S、サイズ)。 リターン odd_str.size()> = even_str.size()?odd_str:even_str。 } ストリング longestPalindrome_odd(ストリング&S、int型のサイズ) { 文字列RES。 以下のために(INT iが= 0 ; I <サイズ; ++ I){ 文字列のsubstr = s.substr(I、1 )。 用(int型、L = I- 1、R = I + 1、L> = 0 && R <=サイズ- 1 - 、R ++ L; ){ もし、(S [L] = S [R]!)ブレーク。 他{ SUBSTR = s.substr(L、R-L + 1); } } もし(substr.size()> = res.size())RES = SUBSTR。 } 戻りRES。 } ストリング longestPalindrome_even(ストリング&S、int型のサイズ) { 文字列RES。 以下のために(INT iが= 0 ; I <サイズ; ++ I){ 文字列のsubstr。 用(int型、L = I、R = I + 1、L> = 0 && R <=、サイズ1 ; 1 - 、R ++ ){ 場合([L] S = S [R]!)休憩; 他{ SUBSTR = s.substr(L、R-L + 1 )。 } } もし(substr.size()> = res.size())RES = SUBSTR。 } 戻りRES。 } }。
2つの動的プログラミング:
ステップ1:状態の定義
[j] [i]はDPがサブストリングS [I、J]はパリンドロームサブストリングであるかどうかを示します。最初の状態を定義してみてください「というトピックが状態を置くために設定されているものを、頼まれる何を。」「状態遷移方程式」は、状態の定義を変更しようと取得することは容易ではない場合次に、「どのような状態転送」を検討し、目的は、まだ取得促進することで、「状態遷移方程式を。」
ステップ2:状態遷移方程式を考えます
このステップは、ステータス定義の分析を与えるために、(文字は頭と尾によると等しい)カテゴリーの議論を行っています。
DP [I] [J] = (S [I] == S [J])とDP [I + 1] [j - 1]
の状態遷移方程式の解析:
実際には、(1)「ダイナミックプログラミング」充填は、2次元テーブル、iとjの間の関係は、I <= J、したがって、このテーブルを埋める必要の上半分のみ。
(2)S [I] == S [J]とjの確立時 - I <3前提、結論を直接することができ、DP [i] [j]は、それ以外の場合は状態遷移を行い、真=。
注:分類技術は状態構造の回転伝達方程式に記載されています。状態空間の分類は、エンドそうで何最適なサブ構造を考えます。これは、問題は小さな問題に対する最適解から最適解を得ることがいかに大きいです。
ステップ3:初期化を考えてみましょう
初期化時間は、対角が1、すなわち、DP [i]は[I] = 1となるように初期化され、単一の文字列パリンドロームである必要があります。
実際には、部品の初期化が省略されています。特定の文字がパリンドロームの場合にのみ、DP [I] [I]は、状態他の基準値ではないからです。
ステップ4:出力を検討
= [J] [i]は長い得DP限り真、 記録され、サブストリング開始位置の長さをインターセプトする必要がないだけでなく、文字列が消費性能をとっているため、この場合の記録パリンドロームストリング「開始位置」と「回文長」ボタンを押します。
ステップ5:圧縮状態が考えられる場合
、充填のプロセス、左下の参考値として。実際には、それを圧縮することができるが、裁判官文の数、書き込みを高め、コードより困難、損失の読みやすさを理解します。ここで状態が圧縮されていません。
以下は注意を払うまでの時間をコーディングの問題です:決意の子供は常に回文文字列、判断の文字列に、次に大きな男の部分文字列の参照を取得する最初のものです。
アイデアは次のとおりです。
図1に示すように、徐々に拡大サブストリング右境界Jの過程で、列挙の左端の位置が起こり得ます。
2、あなたが大から小に、小から大まで列挙することができます左マージンをすることができます。
参照コード2:
クラス解決{ パブリック: ストリング longestPalindrome(ストリングS){ CONST INTのサイズ= s.size()。 もし(s.empty()||サイズ<= 1 ) リターンS。 INT、L = 0、H = 0、SEQ = 0 。 ブールDP [サイズ] [サイズ]。 用(INT J = 1 ; J <サイズ; ++ j)の ための(INT iは= 0 ; iが<= jで; ++ I) { int型 sub_seq = J-I + 1 ; もし(sub_seq < 3 ) { DP [I] [J] = S [I] == S [J]。 } 他 { DP [I] [J] =(S [I] == S [J] && DP [I + 1 ] [J- 1 ])。 } であれば(DP [I] [J] && sub_seq> = 配列){ L = I。 H = J。 SEQ = sub_seq。 } } リターンs.substr(L、SEQ)。 } }。