の場合にセグメントが有効であることを確認したあなたは正しいですmax(segment) - min(segment) + 1 = W。したがって、問題は のすべての長さWのセグメントの最小値と最大値を見つけることになりO(N)ます。
このために、deque Dを使用できます。分を見つけたいとします。D0 ベースのインデックス付けを想定して、要素のインデックスを に格納します。元Aの配列とします。
for i = 0 to N - 1:
if D.first() == i - W:
D.popFirst() <- this means that the element is too old,
so we no longer care about it
while not D.empty() and A[ D.last() ] >= A[i]:
D.popLast()
D.pushBack(i)
それぞれについて、これはindex の要素としてi最小値を与えます。[i - W + 1, i]D.first()
popFirst()から最初の要素を削除しDます。の最初の要素がからステップD以上W離れてiいる場合は、上記の間隔の最小値に寄与しないため、これを行う必要があります。
popLast()から最後の要素を削除しDます。ソート順を維持するためにこれを行います。 の最後の要素がDより大きい要素のインデックスである場合、 の最後A[i]に追加すると順序が崩れます。したがって、ソートされた状態を維持するために、最後の要素を削除し続ける必要があります。iDD
pushBack()の末尾に要素を追加しますD。それを追加した後、D間違いなくソートされたままになります。
これはO(1)(min を見つけるため、上記の疑似コードは です) 各要素が最大 1 回O(n)プッシュおよびポップされるためです。D
これDは、常に 内の関連付けられた値でソートされたインデックスのスライディング ウィンドウになるため、機能しAます。この順序を破る要素にいる場合D、順序が復元されるまで (スライディング ウィンドウ) から要素をポップできます。新しい要素はポップしている要素よりも小さいため、それらが解決に貢献できる方法はありません。
D:startとend. _ 次にD、長さの配列を作成Nすれば完了です。