題目:
有一個整型數組 arr 和一個大小爲 w 的窗口從數組的最左邊滑倒最右邊,窗口每次向右邊劃一個位置。
例如:
數組爲 [4,3,5,4,3,3,6,7],窗口大小爲3時:
[4 3 5] 4 3 3 6 7 窗口的最大值爲5
4[3 5 4] 3 3 6 7 窗口的最大值爲5
4 3[5 4 3] 3 6 7 窗口的最大值爲5
4 3 5[4 3 3] 6 7 窗口的最大值爲4
4 3 5 4[3 3 6]7 窗口的最大值爲6
4 3 5 4 3[3 6 7] 窗口的最大值爲7
如果數組的長度爲 n ,窗口大小爲 w ,則一共可以產生 n - w + 1個窗口最大值。
請實現一個函數。
輸入:整型數組 arr, 窗口大小爲 w。
輸出:一個長度爲 n - w + 1的數組 res ,res[i]表示每一種窗口狀態下的最大值,以本題爲例,結果應該返回 [5,5,5,4,6,7]。
解
暴力解法,時間複雜度爲n x w
進階:使用雙端隊列,隊列從左到右降序排列,遍歷數組時,如果隊列爲空,直接入隊。如果值大於等於當前隊列最右端值,則隊列的右端開始彈出,如果比隊列右端小則入隊,如果隊列爲空,直接入隊。注:也可以使用雙向鏈表
vector<int> getMaxwindow(vector<int>v, int w){
vector<int>ret;
deque<int>help;
if (w < 1 || v.size() < w)
return ret;
int i = 0;
for (i; i < v.size(); i++){
while (!help.empty() && v[help.back()] <= v[i])
//隊列不爲空,且最後一個元素小於等於v[i]則彈出來
help.pop_back();
help.push_back(i);
if (i - w == help.front())//i-w表示左窗口的前一個
//若果i - w == help.front() 表示help中第一個點過期了
help.pop_front();
if (i >= w - 1)//形成了窗口
ret.push_back(v[help.front()]);
}
return ret;