<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      單調隊列是一種用來快速查詢一段長度為n的數(shù)組的一部分的最大最小值的算法。它原理相對簡單,且易于實現(xiàn),并且時間復雜度是接近O(n)的,可以解決很多問題。下面以洛谷P1886滑動窗口 /【模板】單調隊列為例來介紹單調隊列的實現(xiàn)方法。

      先放上題目:

      題目描述

      有一個長為n的序列a,以及一個大小為k的窗口?,F(xiàn)在這個窗口從左邊開始向右滑動,每次滑動一個單位,求出每次滑動后窗口中的最大值和最小值。

      例如:

      The array is [1,3,-1,-3,5,3,6,7],and k=3。

      輸入格式

      輸入一共有兩行,第一行有兩個正整數(shù)n,k。第二行n個整數(shù),表示序列a

      輸出格式

      輸出共兩行,第一行為每次窗口滑動的最小值
      第二行為每次窗口滑動的最大值

      解法介紹:

      單調隊列并不使用queue,而只需要在原序列中維護兩個邊界,分別為l和r,代表研究的部分的左邊界位置、右邊界位置。我們將左邊界的位置初始化為1,右邊界的位置初始化為k,代表最初這個研究部分只包含a[1]到a[k]這些節(jié)點。此時,我們并不知道這個子區(qū)間的最大值和最小值分別是多少,所以我們需要維護一個find函數(shù)來尋找子區(qū)間內的最大、最小值。這里我們進行一次find初始化,并且對最初的最大值、最小值進行記錄。find函數(shù)只需要從l到r進行枚舉查詢即可。

      find函數(shù)代碼實現(xiàn)如下:

       

      1 const int inf=0x3f3f3f3f;
      2 void find(int l,int r){
      3     maxn=-inf;minn=inf;//初始化最大值和最小值
      4     for(int i=l;i<=r;i++){
      5         maxn=max(maxn,a[i]);
      6         minn=min(minn,a[i]);
      7     }
      8 }

       

      接下來我們需要對這個窗口進行滑動操作。我們總共需要向右移動(n-k+1)次,每一次都要進行l(wèi)++,r++的操作。而在操作的時候我們需要維護最值,這也是最為重要的操作。

      我們在維護時要分很多種情況:

      第一種,也是最好處理的一種情況,當在進行l(wèi)++操作之前的l所對應的a[l]既不是上一個窗口所對應的最大值,又不是它所對應的最小值時,刪去這個值并不會影響窗口內的最大值和最小值,這時候我們可以放心的l++,r++,然后用新加入單調隊列的a[r]對maxn和minn進行update更新即可。

      代碼:

       1 void update(){
       2   l++;
       3   r++;
       4   maxn=max(maxn,a[r]);
       5   minn=min(minn,a[r]);
       6 }
       7 //接下來是在循環(huán)中的判斷
       8 if(a[l]!=maxn&&a[l]!=minn){
       9   update();
      10 } 

      第二種,當在進行l(wèi)++操作之前的l所對應的a[l]是上一個窗口所對應的最大值,而不是它所對應的最小值時,刪除a[l]會對新區(qū)間內的最大值造成影響,我們已經(jīng)不知道除了這個被刪除掉的節(jié)點以外,新窗口的最大值是多少,所以我們要重新查找。但是,這種情況不會對最小值造成影響。但是,如果新加入的節(jié)點要大于等于要刪除的節(jié)點,那么刪除掉這個節(jié)點也就無所謂了。所以我們還需要加入一個判斷:

      1 if(a[l]==maxn){//如果左邊界的值等于最大值 
      2     if(a[r+1]>=a[l]){//新加入節(jié)點值大于等于刪除的節(jié)點 
      3         update();//不需要重新查找 
      4     }else{
      5         l++;
      6         r++;
      7         find(l,r);//否則重新查找 
      8     }
      9 }

      第三種,當在進行l(wèi)++操作之前的l所對應的a[l]是上一個窗口所對應的最小值,而不是它所對應的最大值時,我們可以用與第二種情況相同的方式來查找。代碼如下:

      1 if(a[l]==minn){ 
      2   if(a[r+1]<a[l]){
      3       update();
      4   }else{
      5       l++;
      6       r++;
      7       find(l,r);
      8   }
      9 } 

      第四種,也是最為玄學的一種情況,就是當在進行l(wèi)++操作之前的l所對應的a[l]既是上一個窗口所對應的最小值,又是它所對應的最大值的情況。這種情況下直接重新查找就可以了,畢竟這種情況極少,且考慮起來會很麻煩。

      代碼:

      1 if(a[l]==maxn&&a[l]==minn){
      2     l++;
      3     r++;
      4     find(l,r);
      5 }

      最后附上完整代碼:

       1 #include<iostream>
       2 #include<algorithm>
       3 using namespace std;
       4 const int inf=0x3f3f3f3f;
       5 int n,k; 
       6 int l,r;
       7 int a[1000005];
       8 int maxn,minn;
       9 int max_ans[1000005],min_ans[1000005];
      10 void record(int now){
      11     max_ans[now]=maxn;
      12     min_ans[now]=minn;
      13 }
      14 void find(int l,int r){
      15     maxn=-inf;
      16     minn=inf;
      17     for(int i=l;i<=r;i++){
      18         maxn=max(maxn,a[i]);
      19         minn=min(minn,a[i]);
      20     }
      21 }
      22 void update(){
      23     l++;
      24     r++;
      25     maxn=max(a[r],maxn);
      26     minn=min(a[r],minn);
      27 }
      28 int main(){
      29     cin>>n>>k;
      30     for(int i=1;i<=n;i++){
      31         cin>>a[i];
      32     }
      33     l=1;
      34     r=k;
      35     find(l,r);
      36     for(int i=1;i<=n-k+1;i++){
      37         record(i);
      38         if(a[l]!=maxn&&a[l]!=minn){
      39             update();
      40         }else if(a[l]==maxn&&a[l]==minn){
      41             l++;
      42             r++;
      43             find(l,r);
      44         }else if(a[l]==maxn){
      45             if(a[r+1]>a[l]){
      46                 update();
      47             }else{
      48                 l++;
      49                 r++;
      50                 find(l,r);
      51             }
      52         }else{
      53             if(a[r+1]<a[l]){
      54                 update();
      55             }else{
      56                 l++;
      57                 r++;
      58                 find(l,r);
      59             }
      60         }
      61     }
      62     for(int i=1;i<=n-k+1;i++){
      63         cout<<min_ans[i]<<' ';
      64     }
      65     cout<<endl;
      66     for(int i=1;i<=n-k+1;i++){
      67         cout<<max_ans[i]<<' ';
      68     }
      69     cout<<endl;
      70     return 0;
      71 }

       

      posted on 2020-10-15 17:32  郭謙  閱讀(479)  評論(0)    收藏  舉報
      主站蜘蛛池模板: av中文字幕在线二区| 99亚洲男女激情在线观看| 国产精品麻豆va在线播放| 亚洲国产日韩伦中文字幕| 日韩av在线不卡一区二区三区 | 中文字幕日韩有码第一页| 国内精品无码一区二区三区| 99久久精品费精品国产一区二区| 视频一区二区不中文字幕| 国产av国片精品一区二区| 人人色在线视频播放| 国产毛片精品一区二区色| 国产高清自产拍av在线| 国产精品1区2区3区在线观看| 国产成年女人特黄特色大片免费| 亚洲激情国产一区二区三区| 精品无码久久久久久久久久| 日本黄页网站免费观看| 精品久久综合日本久久网| 日韩一区二区三区三级| av中文字幕一区二区| 亚洲熟妇中文字幕五十路| 色成年激情久久综合国产| 免费现黄频在线观看国产| 亚洲一区二区av偷偷| 啪啪av一区二区三区| 亚洲欧洲av一区二区| 中文字幕在线国产精品| 4hu亚洲人成人无码网www电影首页| 亚洲岛国成人免费av| 人妻影音先锋啪啪AV资源| 少妇人妻偷人偷人精品| 色视频不卡一区二区三区| 国产精品无码一区二区桃花视频 | 国产精品麻豆成人av网| 亚洲色一区二区三区四区| 成在人线av无码免费| 亚洲欧洲日韩国内精品| 萨嘎县| 非会员区试看120秒6次| 人妻人人做人做人人爱|