1. 程式人生 > 實用技巧 >牛客 滑動視窗

牛客 滑動視窗

題目連結:https://ac.nowcoder.com/acm/problem/50528

思路:雙端佇列處理 假設求的是最小值 那麼放進來的數和佇列尾比較,如果佇列尾的數比當前這個數大,那麼佇列尾的數刪去,他已經不可能成為最小值了

然後在看以下佇列頭的範圍有沒有出了視窗 這樣處理後此時的佇列是非嚴格單調遞增的,隊首即為最小值 求最大值同理

要注意的是 存的是 下標 而不是值 每個數只會入隊出隊一次 所以 時間複雜度為 o(n)

幾種雙端佇列的操作 deque<int>q

push_back(x)/push_front(x) 把x把x放在隊尾/隊首

back()/front() 訪問(不刪除)後隊尾/隊首元素

pop_back() pop_front() //刪除隊尾/隊首元素

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=1e6+10;
 7 const int mod=998244353;
 8 int a[maxn];
 9 
10 
11 int main()
12 {
13     ios::sync_with_stdio(false
); 14 cin.tie(0); 15 int n,k; 16 cin>>n>>k; 17 for(int i=1;i<=n;i++) 18 { 19 cin>>a[i]; 20 } 21 vector<int>ans1; 22 deque<int>q; 23 for(int i=1;i<=n;i++) 24 { 25 while(!q.empty()&&a[q.back()]>=a[i])
26 q.pop_back(); 27 if(!q.empty()&&q.front()==i-k) 28 q.pop_front(); 29 q.pb(i); 30 if(i>=k) 31 ans1.pb(a[q.front()]); 32 } 33 q.clear(); 34 vector<int>ans2; 35 for(int i=1;i<=n;i++) 36 { 37 while(!q.empty()&&a[q.back()]<=a[i]) 38 q.pop_back(); 39 if(!q.empty()&&q.front()==i-k) 40 q.pop_front(); 41 q.pb(i); 42 if(i>=k) 43 ans2.pb(a[q.front()]); 44 } 45 for(auto &v:ans1) 46 cout<<v<<" "; 47 cout<<'\n'; 48 for(auto &v:ans2) 49 cout<<v<<" "; 50 51 52 53 54 55 }
View Code