1. 程式人生 > >滑動最小值 /// deque巧用

滑動最小值 /// deque巧用

i+1 i++ d+ spa 繼續 open 最小值 n-k for

題目大意:

輸入n,k;給定長度為n的數列a0,a1,...,a(n-1)

求數列b=min(ai,ai+1,...,ai+k-1) i=0,1,...,n-k;

技術分享圖片
#include <bits/stdc++.h>
using namespace std;
int n,a[105],k,b[105];
int deq[105]; // 模擬雙端隊列 保存對應a[]下標
int main()
{
    while(~scanf("%d%d",&n,&k)) {
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        
        
int head=0, tail=0; // 賦零清空隊列 for(int i=0;i<n;i++) { while(head<tail && a[deq[tail-1]]>=a[i]) tail--; /// 若deq[]對應的值>=a[i] 則一直推到比a[i]小或沒有值 deq[tail++]=i; // 更新隊列 if(i-k+1>=0) { // 若已滿足k個 b[i+k-1]=a[deq[head]]; //
將前k個內最小值存入b[] if(deq[head]==i-k+1) head++; /// 若隊頭的最小值已經是當前k個內的第一個 /// 即繼續往後時 deq[head]已經超出k個的限制 /// 則舍棄這個最小值 head後移向下一個最小值 } } for(int i=0;i<n-k;i++) printf("%d%c",b[i], i==n-k ? \n: ); }
return 0; } /* n=5,k=3 a={1,3,5,4,2} i a[] deq[] b[] 0 1 0(1) 1 3 0(1) 1(3) 2 5 0(1) 1(3) 2(5) 1 3 4 1(3) 2(5) 3(4) 1(3) 3(4) /// 因為5>4 tail--; 3(4) /// 1(3)已經不在k個的範圍內 刪掉 head++; 4 4 2 3(4) 4(2) 4(2) /// 因為4>2 tail--; 2 最後 b={1,4,2} */
View Code

滑動最小值 /// deque巧用