leetcode239。最大スライディングウィンドウ(単調なキューまたはヒープ)

トピック

整数の配列numsが与えられると、サイズkのスライディングウィンドウが配列の左端から右端に移動します。スライディングウィンドウにはk個の数字しか表示されません。スライディングウィンドウは、一度に1つの位置だけ右に移動します。

スライディングウィンドウの最大値を返します。

例1

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

単調キューソリューション

単調キュー

void push_front(n)//在队头插入n
void push_back(n)//在队尾插入n
void pop_front()//删除队首元素
void pop_back()//删除队尾元素
int front()
int back()

deque<int>window添え字を格納する変数を宣言しましたこの変数には、次の特性があります。

  • 変数のフロントエンド(つまり、window.front())は、このトラバーサルの最大値の添え字です。
  • 新しい番号に遭遇すると、新しい番号を2項目キューの最後(つまり、window.back())と比較します。最後が新しい番号よりも小さい場合、最後は最後まで破棄されます。キューが新しい数が多いか、キューが空の場合にのみ停止します。アプローチは、スタックを使用して括弧を一致させるのと少し似ています。
  • deque内のすべての値はウィンドウ範囲内にある必要があります

最初の機能は、各ウィンドウが1グリッドスライドした後に最大値を取得するのが便利なことです。これは、window.front()から直接取得できます。

機能2により、キュー内の要素が最初から最後まで降順であることが保証されます。キュー内のウィンドウには数字しかないため、実際には、それらは1番目、2番目、3番目...の数字です。窓。

特徴3は質問の意味に応じて設定されています。しかし、実際には現在の添え字をwindow.front()と比較するだけです。理由を考えてみてください。

回答:ウィンドウの最初の要素がウィンドウのwindow.front()である限り、2番目と3番目の要素が範囲内にあるかどうかは関係ありません。答えは一番の要素でなければならないからです。window.front()がウィンドウにない場合は、ポップアップされ、2番目に大きい要素が最初に大きい要素になり、3番目に大きい要素が2番目に大きい要素になります。

コードを記述するプロセスでは、例外がスローされないように、キューが空かどうかを常に確認する必要があります。

時間の複雑さ

ここに画像の説明を挿入

コード

vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n=nums.size();
		deque<int>q;
		for(int i=0;i<k;++i)//i表示滑动窗口的最右侧下标 
		{
			while(!q.empty()&&nums[i]>nums[q.back()])
				q.pop_back();
			q.push_back(i);
		}
		vector<int>result; 
		for(int i=k;i<n;++i)//i表示滑动窗口的最右侧下标 
		{
			while(!q.empty()&&nums[i]>nums[q.back()])
				q.pop_back();
			q.push_back(i);
			if(q.front()<=i-k)
				q.pop_front();
			result.push_back(nums[q.front()]);
		} 
    }

おすすめ

転載: blog.csdn.net/weixin_45019830/article/details/115311278