牛客 滑動視窗
阿新 • • 發佈:2020-07-15
題目連結: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(falseView Code); 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 }