leetcode0005最長の回文:動的計画法、分割統治キャッシュバックワード

  前のブログでは、使用の分割統治へのパーティションソリューションとその理由を書きました。

  サブ分割統治私たちの問題を定義することで、我々はこのように私たちは、解空間の繰り返し構造を見つけるために貢献し、計算の各ステップの意味をインスタンス化します。

  パーティションの間に、我々は状態遷移方程式であるとの問題の解決策のセグメンテーションと表現を見つけます:

 

   パーティション全体の演算処理は、問題の最終的な解を得るために、収束副問題のソリューションまで、二つの段階、セグメンテーションダウンに分割されます。

  次にキャッシュは、我々は解決策の概要まで大きな問題の裏になる問題の最小サイズからステップにより溶液のステップです。

  実際には、状態遷移方程式を用いて、我々は、需要の問題の再帰的な溶液の小さな問題から直接、省略最終溶液をセグメンテーションするステップができます。

  例えば、上述した状態遷移式、Iインクリメント/デクリメントjを我々は直接最小サブ問題から、次に、当該分割された場合:増加送達のためにキャッシュを埋めるために、I / Jの高い順に、最小のjを開始してI最大、元の問題の解決策は、プッシュに決定しました。

  なお、充填プロセスの境界の間、上述した状態遷移式の二種類がある場合には境界。

  1. iは文字列の長さ未満である、私は+ 1、さもなければ範囲外です。 

  0より2. jは大きいが、J-1が境界外さもなければあろう。

  より大きいまたは右境界として3 J I、Jセマンティクスに等しく、iは意味論の左端です。

  以来3及びI> = 0、保証が3 2、1、3は、我々は唯一の2行の境界の場合は、することができ考慮する必要があることを確認することですので。

  それは、効率を、そこにしません変更に入れて改善するための分割統治イェジンハオ、動的プログラミングソリューションスペースがあるかどうか、いくつかの質問を少し感情をやった後、それは我々が解空間の繰り返し構造を見つけることによって、ダブルカウントを避けることです。構造的な問題の私達の定義に基づいて。問題のより合理的な構造の定義は、より多くの再利用可能な部品我々は、解空間を見つけることができます。

  そして、ちょうど貪欲とバックトラッキングソリューションスペースの検索技術は、特定のシーンの顔に、私たちは特定のシーンで必要な思考のこのラインを、持っている必要があります、というよりも効率を向上させることができます。

  避けプルーニングは、無効な計算、空間の直接の狭い理解しています。問題そのものの私達の定義に基づいて。

    int型のmaxLength = 0 ;
    文字列ANS = "" ;

    公共の 最終文字列DP(文字列のソース){
         もし(ソース== NULL || source.length()== 0 ){
             リターン "" 
        }
        INT長= source.length()。
        INT [] []キャッシュ= 新しい int型[長さ]、[長さ];

        intは ;左> = 0 left-- =左長-1 {)
             のためのINT右=左、右の<長さ、右++ ){
                 // 边界处理
                場合(==左右){
                    キャッシュ[左] [右] = 1 続け;
                }
                もし(左==長-1 ){
                     場合(キャッシュ[左] [右-1] == 1 && source.charAt(左)== source.charAt(右)){
                        キャッシュ[左] [右] = 1 int型 tempLength =右、左。
                        もし(tempLength> maxLengthの){
                            maxLength = tempLength。
                            ANS = source.substring(左、右+ 1 )。
                        }
                        続け;
                    }
                    キャッシュ[左] [右] = -1 ;
                }
                // サブストリング負主に直接負列
                IF(キャッシュ[左+ 1] [右回転1] == - 1 ){
                    キャッシュ[左] [右] = -1 ;
                    続け;
                }
                // パリンドローム配列をサブストリング、メインストリング決定
                チャー leftChar = source.charAt(左);
                 チャー rightChar = source.charAt(右);
                 IF(!= LeftChar rightChar){
                    キャッシュ[左] [右] = -1 ;
                    続け;
                }
                // メインストリングはパリンドローム配列、更新結果である
                INT tempLength右= ;左
                 IF(tempLength> maxLengthの){
                    maxLength = tempLength。
                    ANS = source.substring(左、右+ 1 )。
                }
                キャッシュ[左] [右] = 1 
            }
        }
        もし(maxLengthの== 0 ){
             戻り source.substring(0,1 )。
        }
        戻り値は、ANS;
    }

 

  

おすすめ

転載: www.cnblogs.com/niuyourou/p/12483830.html