題目描述
有乙個整型陣列arr和乙個大小為w的視窗從陣列的最左邊滑到最右邊,視窗每次向右邊滑乙個位置,求每一種視窗狀態下的最大值。(如果陣列長度為n,視窗大小為w,則一共產生n-w+1個視窗的最大值)
輸入描述:
第一行輸入n和w,分別代表陣列長度和視窗大小
第二行輸入n個整數x,表示陣列中的各個元素
輸出描述:
輸出乙個長度為n-w+1的陣列res,res[i]表示每一種視窗狀態下的最大值
示例1輸入
複製8 3
4 3 5 4 3 3 6 7
輸出複製
5 5 5 4 6 7
說明例如,陣列為[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
輸出的結果為
備註:10000001≤w≤n≤1000000
−1000000≤x ≤1000000
思路:剛開始拿到這個題,我想到的是遍歷整個陣列,每次拿到乙個視窗陣列,再去遍歷得到最大值,直到陣列遍歷完,得到最後的結果陣列ret,整個陣列長度是n,視窗大小是n,則這樣做的時間複雜度是o(m*n)。
參考了《程式設計師**面試指南》這本書,學到了o(n)的解法。
利用乙個雙端佇列d,拿例子v[4,3,5,4,3,3,6,7],視窗大小為3來說。
1.當d為空或者v[d.back()]>v[i]時,直接d.push_back(i);(佇列裡面存的下標)
2.當d不為空並且v[d.back()]<=v[i]時,d.pop_back();這一步迴圈進行,直到不滿足條件時跳出迴圈 ,再d.push_back(i);
3.if(d.front()==i-w),d.pop_front();
此時說明佇列頭部元素過期,不在此視窗內了,需要彈出去.
4.if(i>=w-1) ,ret.push_back(v[d.front()]);
滿足此條件說明需要求視窗最大值,就是佇列的首元素為下標的值。
ps:如果實在看不懂,拿例子模擬一遍吧。
**實現:
#include
#include
#include
using namespace std;
vector
max_window
(vector
& v,int w)
return ret;
}int main()
vector ret=
max_window
(v,w)
;for
(size_t i=
0;isize()
;i++
) cout<<<
" ";
cout
}
生成視窗最大值陣列
有乙個整型陣列arr和乙個大小為w的視窗從陣列的最左邊滑到最右邊,視窗每次向右邊滑乙個位置,求每一種視窗狀態下的最大值。如果陣列長度為n,視窗大小為w,則一共產生n w 1個視窗的最大值 輸入描述 第一行輸入 n 和 w 分別代表陣列長度和視窗大小 第二行輸入 n 個整數 x ix i xi 表示陣...
生成視窗最大值陣列
說明 本文是左程雲老師所著的 程式設計師面試 指南 第一章中 生成視窗最大值陣列 這一題目的c 復現。感謝左程雲老師的支援。題目 有乙個整形陣列 arr 和乙個大小為 w 的視窗從陣列的最左邊滑到最右邊,視窗每次向右邊滑動乙個位置。例如,陣列為 視窗大小為3時 4 3 5 4 3 3 6 7 視窗中...
生成視窗最大值
生成視窗最大值陣列 題目 有乙個整型陣列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...