ブローアップサブパリンドロームO(N)

手づくり同型のプロパティ:均質チャネリングは、最小と最大の文字表現を持っています。

最長の回文をチャネリングサブ:

1.まず、暴力行為:(nは三者)

開始及び各列挙の終わり、その後一方向走査パリンドロームサブチャネリングではないと判断します。

2.ザセンター拡散法、(N側)

各中間点の列挙は、スプレッドアウト、彼は回文の長さの中心地であった参照することは、サブチャネリングの数です。

証明するのは簡単です:N側の複雑さ

3.O(N)アプローチ。

https://blog.csdn.net/afei__/article/details/83214042?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task ;

私の理解:とKMPの拡大は、我々はない繰り返し、POおよびEX [PO]の順で壊れてセットして、KMPを拡張し、やや似ており、その後、我々はそれが直接的に含まれている場合、私は、スキャン内部の可能な答えに含まれているかどうかを議論します割り当ては、スキャンに引き続き含まれていませんでした。

我々は、拡散中心の方法を改善しました

1.思想:1)文字列Sの元の文字のそれぞれの間はそう得るために、また、S字の頭部と尾部に挿入された文字Sに表示されません(この場合、「#」を意味によって示される)、挿入されています2 * s.length()+ 1のS_new新しい文字列の長さ、レンは、長さが奇数(のみ美的効果、空白文字が当てはまらない表す)であることを確認。      

 例:S:B BはA B A     

       S_new:#A#A ### Bは#Bは## B   

2)各文字によればS_newアレイに文字間隔の右端の文字、レンのパリンドローム最長サブストリング、即ちS_new [I] -S_new [R]はS_new [I]のある中心得られます右セクションパリンドローム最長ストリング(S_new [2I-R] -S_new [R]はS_new [i]の最長サブストリングパリンドロームの中心などにある)、レン[I] = R - I + 1。

       S_new:#A#A ### Bは#Bは## B

     :1 2 3 2 1 4 1 4 1 2 5 2 1 2 1       

自然配列レン:レン[I] - 1は、S、パリンドロームサブストリングの長さが最長の中心として[I]レンです。各文字の両側にS_newに新しい文字「#」は見かけ上「#」を観察しているので、1 - 順S_new最長のサブストリングS_newにおける回文長[I]は2Len [i]を中心としますレンである原稿1の文字の数よりも多くなければならない[i]は、そうではない真のパリンドロームサブストリングの長さレン[I] - 1、最も長いサブストリングパリンドロームMath.max(LEN)の長さ - 1。   

3)レン解くアレイ(線形複雑度(O(N)))。      

。AトラバースS_newアレイは、私が最も長いサブストリング回文レン[I]の中心としてS_new [I]を解決するために、すなわち、現在の場所を横断しています。     

  - 中心sub_middで発現1 sub_midd = Len.indexOf(Math.max(LEN)レン前アレイの最大値はIで得られた位置、sub_side = sub_midd +レン[sub_midd]を示している:Bは、2つのパラメータを設定します。出発の右端位置のパリンドローム最長のサブストリングは、各計算sub_middとsub_side後に更新する必要が0にS_newのsub_sideをsub_middと、最初の文字S_newから数え。     

 

 

 

。Cいつ<sub_side、sub_midd対称点jにIをとっ(J = 2sub_midd - I、I <= sub_side、2sub_middので以来 - sub_side <= J <= sub_midd);場合レン[J] <sub_side - 私S_new [J]に最長のサブストリングはパリンドロームS_new最長ストリング内の中央に配置されたとき、即ちパリンドローム[sub_midd】中心として、私ので、sub_midd対称にJ、レン[I] =レンを発見[J];レン[J]> = sub.side - S_newにおけるI説明パリンドローム配列[i]の中心とはsub_side越えて延びることができる、及びsub_sideよりいくつか大きいが一致していないので、sub_sideから+1位は、マッチが失敗した後まで、マッチングを開始し、そして対応sub_midd sub_sideを更新するとlen [i]は、      

 

 

 

 時間I> sub_sideが、それはS_newに示しD [i]のマッチを探し始めていない最長のサブストリングパリンドロームので、一致を見つける必要があり、対応するアップデートsub_side sub_middとレン[i]の後の中心として、 。

 

 

 

私は理解して:

実際には、我々は対称の各スキャンとsub_side、使用回文文字列をsub_midしまった、私たちはその答えの内側かどうかを判断する必要があり、我々は比較的ダウンスキャンを続行しません。

これは、中央のDP拡散法の一種です。

そして、何が、性質は内容によってプッシュに追求して、解決されている回避の再スキャンを使用して、いくぶん同様のアイデアを機能することを、Z。

ボイドgetlen(CHAR * STR)
{
 int型ANS = 1、腕= 0。
 memset(LEN、0、はsizeof(LEN))。
 int型ミッド= 0、サイド= 1、I、J、R。
 LEN [0] = 1;
 ため(I 1 =; I <R、I ++)
 {
  J = 2 *ミッドI。
  IF(J <0 || J-lenの[J] <=半ばでlen [中間])
  {
   R =サイドI。
   もし(R == 0)側++、R = 1。
   一方(IR> = 0 && STR [IR] == STR [側])
   {
    R ++。
    サイド++;
   }
   ミッド= I。
   LEN [I] = R。
  }
  他
   LEN [I] = LEN [J]。
  IF(ANS <LEN [I])
  {
   ANS = LEN [I]。
   腕= I;
  }
 }
 もし(ANS-1 <2)
 COUT << "いいえ溶液\ N!"。
 他の
 {
  INT R =腕+ lenの[腕] -1、L =腕- (LEN [腕] -1)。
  r--の;
  L = L / 2、R = R / 2。
  COUT << L << " "<< R <<" \ n";
  以下のために(INT iがLを=; I <= R; I ++)
   slove(S1 [I])。
  裁判所未満<< "\ n"は、
 }
}

おすすめ

転載: www.cnblogs.com/hjw201983290498/p/12589327.html