件名の説明:
指定された整数配列の乱れ、最長見出さ立ち上がりシーケンスの長さ。
例:
入力:[10,9,2,5,3,7,101,18]
出力:4の
説明:最長の配列は、その長さは4であり、[2,3,7,101]増加します。
説明:
様々な組み合わせがあなただけの出力に対応する長さを必要とし、シーケンスを増加させることができます。
あなたのアルゴリズムの時間計算量はO(N2)でなければなりません。
高度:あなたは(N Nをログ)Oにアルゴリズムの時間の複雑さを軽減することができますか?
アイデアの分析:
アイデアは:被験者を促し、動的プログラミングは、この問題のO(N ^ 2)溶液の複雑さを使用することができます。DP直接配列、帰りから上昇最大電流配列を有する各メモリ素子を使用して、状態遷移方程式は、DP [I] = MAX(DP [I]、DP [J] +1)に更新され、 jは()をdp.sizeに対するI + 1の値です。
2考える:により高度な要件にしている対象のニーズが減少する複雑性O(NlogN)は、LOGN正当化は、この複雑さを軽減するためにバイナリ検索を使用するのではと思います。実際には、このアイデアは、配列、反復のNUMS列のテール部分を維持することで、ツリーの現在の値よりも大きな尾を見つけるために、各アレイは、交換ならば、現行の値はテール配列を追加した場合ではありません。その理由は、その後の検索では、交換のために、我々は原因要素の現在の尾さらに小さくし、より長い配列を見つけることができます。実際には、新たな要素を追加する場合にのみ、最長の配列のサイズを変更しますので、アレイのテール長の長さは、現在の最も長いシーケンスに維持されます。ここではバイナリサーチコードが直接LOWER_BOUND()関数を呼び出して使用回数を探します。次のようにこの機能の説明は次のとおりです。
また、機能UPPER_BOUND別の区別は、戻り値が第1の値valアドレスよりも大きいことに注意してください。最初の最初のパラメータは、最初のアドレスの連続したスペースで、最後のアドレスは、連続した領域の終わりで、valは発見される値です。前提コールLOWER_BOUNDは()の要素がの(増分)を注文している、この連続空間です。
次いでLOWER_BOUND()戻り値は最初の値valは、最初に減算することにより、このアドレスは、valが以上添字である最初の値を取得する以上アドレスであります
コード:
考えました:
1 クラスソリューション{ 2 公共: 3 INT lengthOfLIS(ベクトル< INT >&NUMS){ 4 もし(nums.size()== 0 ) 5 リターン 0 。 6 ベクター< INT > DP(nums.size()、1 )。 7 のための(int型 I = nums.size() - 1 ; I> = 0 ; i-- ) 8 { 9 ための(int型 J = iは+ 1、J <nums.size(); J ++ ) 10 { 11 であれば(NUMS [J]> NUMS [I]) 12 { 13 DP [I] = MAX(DP [I]、DP [J] + 1 )。 14 } 15 } 16 } 17 int型の最大値= 0 。 18 のために(int型 I = 0 ; iが<; I ++はdp.size() ) 19 { 20の 場合(DP [I]> MAX) 21 、最大= DP [I]。 22 } 23 リターン最大; 24 } 25 }。
2考えます:
1 クラスソリューション{ 2 公共: 3 INT lengthOfLIS(ベクトル< INT >&NUMS){ 4 もし(nums.size()== 0 ) 5 リターン 0 。 6 ベクター< INT > RES。 7 ためには(int型、I = 0 ; iが(nums.sizeを<); iが++ ) 8 { 9 オートITER = LOWER_BOUND(res.begin()、res.end()、NUMS [I])。 10 であれば(ITER == res.end()) 11 res.push_back(NUMS [I])。 12 他 13 * ITER =のNUMS [I]。 14 } 15 リターンres.size()。 16 } 17 }。