質問の意味は:アレイは、各列の高さのヒストグラムを表して考えると、各列の幅は、ヒストグラムの最大の矩形領域を見つけ、1です。
この質問は、まず、I〜Jの間の長方形の面積の2次元配列で、DPを参照してくださいと思った最大検索領域を得るために、再び横断して、時間計算量はO(N-である2)。これは時間が出ていますコードは以下の通りであります:
クラスソリューション(オブジェクト): DEF largestRectangleArea(セルフ、ハイツ): "" " :タイプハイツ:リスト[INT] :RTYPE:int型 " "" N- = LEN(ハイツ) IFのn - == 0:リターン(0) #1 )初期行列DP:DP [I] [j]は高さを表す[I:(J +) 1] 列の最短の高さとの間の = [0、DP 用 J におけるレンジ(N)] のための I における(N)レンジ] #2)ここで、つなぎ処理 のために I におけるレンジ(N): DP [I] [I] = ハイツ[I] IFI <1-N-:DP [I]は[I + 1] =分(ハイツ[I]、ハイツ[I + 1 ]) #3)再帰関係を確立する:右上DIAGから斜め再帰的に注意してください #DP [I] [j]の値がDPであるべきである[I + 1] [j -1]、高さ[I] 三の最小の高さ[J] のための J でレンジ(2 、N-): のための私はで範囲(N- J): DP [I] [Iが Jを+] =分(DP [I + 1] [私はJ-を+ 1]、ハイツ[I]、ハイツ[Iは+ J]) #4)DP行列検索を横切ります最大高さ[I:(J + 1)] DP [I] [J]の矩形領域である*(I-J + 1) ANS = 0 のための I におけるレンジ(N) のための J でレンジ(I、 N-): ANS= MAX(ANS、DP [I] [J] *(J-I + 1 )) リターン(ANS)
:以下はO(n)のソリューション、単調なスタックを使用する(この記事の単調なスタックの最後には非常に良いですhttps://zhuanlan.zhihu.com/p/26465701 Youtubeでbasketwangに完全に従った溶液(リンク)は、()https://www.youtube.com/watch?v=KkJrGxuQtYo)。アイデアは、すべての部分で(IDX)を含む最大の矩形を見つけるために、各列IDXために、必要なヒストグラム矩形の最大値は、最大{最大矩形(IDX)}に等しくなければなりません。フォーカス:! !!全ての矩形部分(IDX)の最大値が含まれているIDXカラムの列の左右の高さがより大きいかまたは列IDXの高さに等しくなければなりません!!!その後、次のタスクは、柱の左右に矩形(IDX)を見つけることである、(I)の矩形の領域である高さ[IDX]左によって、および右の境界(矩形幅)から乗算(高い長方形)。I /右の境界を左長方形は、実際に最初の[IDX]小後(左)/フロント高さの高さIDXフロント/バック比の数(右)ベクターである:以下に示すように
1 | ||||||||
1 | 1 | 1 | ||||||
1 | 1 | 1 | ||||||
... |
|
1 | ... | 1 | ... | 1 | ... | |
1 | 1 | 1 | 1 | |||||
1 | 1 | 1 | 1 | 1 | ||||
1 | 1 | 1 | 1 | 1 | ||||
左 | 左+ 1 | IDX | 右-1 | 右 |
我々は単調に増加スタックを使用する場合は、(名前が示すように、ハイツ[先頭の要素]> =高さ[要素スタックボトム]です)
1)単調に増加するスタックを確立:高さ[先頭の要素+1]> =高さ[トップ要素]は、我々は単調増加性を維持するためには、(先頭の要素+1)スタックにプッシュを入れた場合は、
2)左右の手を見ている:私たちは高さ[先頭の要素1] <[先頭の要素]の高さに遭遇したとき、我々は右のポインタを見つけます。その中に左ポインタはどこですか?(症例の重複数が有していてもよいことに留意されたい覚え、スタック高さ[トップ要素]> =高さ[スタック要素の元トップ]で単調増加スタックなので、それは、前の要素がスタックの最上部左ループ反復の数をスキップしつつを用いて、)コードを参照してください。
3)現在の最大長方形のトップ素子面積を計算する:矩形の領域(上部要素)=高さ[トップ要素] * [右(左+ 1 )]。
4)上部要素の計算された最大矩形領域:ここでは、矩形領域(上部要素)はそれをポップする次、一度計算され、最大面積の長方形を最上位要素によって計算され、このとき右ポインタそれが最大の長方形の右境界ということはまだ可能性があるため、移動しないでください。
取引の5)最後の残りの部分:すべての要素が高さを(いくつかは、スタックした後であったかもしれない)をスタックすることであったとき、スタックが空でない場合、最大の残りの要素の矩形の右辺がmystackなければならない[-1] 1は、それはまだ前の要素を残しました
クラスソリューション(オブジェクト): DEF largestRectangleArea(セルフ、ハイツ): "" " :タイプハイツ:リスト[INT] :RTYPE:int型 " "" N- = lenは(ハイツ) #は、極端な値を決定し たIFのn - == 0:リターン( 0) #の初期化単調スタック、および右ポインタ、必要に最終的な答えが返される myStack = [] 右、ANS = 0,0 #循環中に 一方が右<N- #右ポインタは、高さの長さ超えることができない #1 単調増加のメンテナンス IFレン( myStack)== 0 またはハイツ[右]>ハイツ= [myStack [-1 ]: mystack.append(右) 右 + 1 =。 #見ると、左、右ポインタ 他: #は、他に入るとき、私たちは、ポインタの右の位置を発見した。この時点ためハイツ[右] <ハイツ[myStack [-1]] #トップ要素をポップし、それ以降の領域計算のために記録 IDX = mystack.pop() # 、矩形などの重複数は、我々はスキップすることができ、最大値に対応する座標が以前の図面を繰り返すことと同じである 一方、 LEN( myStack)> 0 とハイツ[IDX] ==ハイツ[myStack [-1 ]:mystack.pop() #現在のスタックの最上位の要素の左場合、スタックが空でない場合、IDX前飛び出していません、先行素子積層体 位スタックが空である場合、高さ[IDX]より小さくない数左高さは矩形の左端の左前方から、存在しない、それはあるべきである-1 #スタックが空の場合のときのみである理由話し合いますか?私たちは、スタックのすべての要素を持っているので、0より大きい #はスタックにスタックが、我々はここだけで議論することができないとき-1に初期化されていませんか?ありません!矩形の高さが[-1]、の高さではない、次の高さに取られる;第二次スタックが依然として空である、mystackに失敗左[-1]与えられ =左-1 IFでlen(myStack )== 0 他 myStack [-1 ] ANS = MAX(ANS、ハイツ[IDX] *(1-右、左)) #のここでの注意は、右に更新されていません #をスタックが空の場合の要素が処理されたように、リターン結果は、 IF LEN(myStack)== 0:リターン(ANS) #は、そうでない場合、スタックは単調であり、この時間は、残りのすべての矩形の右境界は、上部要素+1でなければならない 右= myStack [-1] +1 一方myStack。 IDX = mystack.pop() 左 = -1 IFでlen(myStack)== 0 他 mystack [-1 ] ANS = MAX(ANS、高さ[IDX] *(左右-1 )) のリターン(ANS)