• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            poj 2823 Sliding Window 單調隊列

               這道題的意思是給定一個長N的整數序列,用一個大小為K的窗口從頭開始覆蓋,問第1-第N-K次窗口里面最大的數字和最小的數字。
               剛開始還以為優先級隊列可以做,發現無法刪除最前面的元素。估計用線段樹這個題也是可以解得。用這個題學了下單調隊列。
               
               單調隊列正如其名,是一個從小到大排序的隊列,而且能夠保證所有的元素入隊列一次出隊列一次,所以平攤到每個元素的復雜度
            就是O(1)。
               對于這個題單調隊列的使用。以序列1 3 -1 -3 5 3 6 7舉例。
               1)元素類型:一個結構體,包含數字大小和位置,比如(1,1),(3,2)。
               2)插入操作:從隊尾開始查找,把隊尾小于待插入元素的元素全部刪除,再加入待插入的元素。這個操作最壞的
            情況下是O(n),但是我們采用聚集分析的方法,知道每個元素最多刪除一次,那么N個元素刪除N次,平攤到每一次
            操作的復雜度就是O(1)了。
               3)刪除隊首元素:比如本文給的那個題,窗口一直往后移動,每一次移動都會刪除一個元素,所以很可能隊首會是要
            刪除的元素,那么每次移動窗口的元素要進行一次檢查,如果隊首元素失效的話,就刪掉隊首元素。

               代碼的實現,我是包裝deque實現了一個模版類。速度很不好,居然跑了11s多才過,幸虧給了12s的時間,看status又500多ms
            就過了的。估計數組實現會快很多。

               代碼如下:
            #include <stdio.h>
            #include <deque>
            #include <algorithm>
            using namespace std;
            #define MAX_N (1000000 + 100)
            int nNum[MAX_N];
            int nN, nK;

            struct Small
            {
                int nValue;
                int nIndex;
                Small(int nV, int index):nValue(nV), nIndex(index) {}
                bool operator < (const Small& a) const
                {
                    return nValue < a.nValue;
                }
            };

            struct Big
            {
                int nValue;
                int nIndex;
                Big(int nV, int index):nValue(nV), nIndex(index) {}
                bool operator < (const Big& a) const
                {
                    return nValue > a.nValue;
                }
            };

            //單調隊列
            template <typename T> class Monoque
            {
                deque<T> dn;

            public:
                void Insert(T node)
                {
                    int nPos = dn.size() - 1;
                    while (nPos >=0 && node < dn[nPos])
                    {
                        --nPos;
                        dn.pop_back();
                    }
                    dn.push_back(node);
                }

                int Top()
                {
                    return dn.front().nValue;
                }

                void Del(int nBeg, int nEnd)
                {
                    if (dn.size() > 0)
                    {
                        if (dn.front().nIndex < nBeg || dn.front().nIndex > nEnd)
                        {
                            dn.pop_front();
                        }
                    }
                }
            };

            int main()
            {
                while (scanf("%d%d", &nN, &nK) == 2)
                {
                    int i;
                    for (i = 0; i < nN; ++i)
                    {
                        scanf("%d", &nNum[i]);
                    }
                    Monoque<Small> minQ;
                    Monoque<Big> maxQ;

                    for (i = 0; i < nK; ++i)
                    {
                        minQ.Insert(Small(nNum[i], i));
                    }

                    for (i = 0; i < nN - nK; ++i)
                    {
                        printf("%d ", minQ.Top());
                        minQ.Insert(Small(nNum[i + nK], i + nK));
                        minQ.Del(i + 1, i + nK);
                    }
                    printf("%d\n", minQ.Top());

                    for (i = 0; i < nK; ++i)
                    {
                        maxQ.Insert(Big(nNum[i], i));
                    }

                    for (i = 0; i < nN - nK; ++i)
                    {
                        printf("%d ", maxQ.Top());
                        maxQ.Insert(Big(nNum[i + nK], i + nK));
                        maxQ.Del(i + 1, i + nK);
                    }
                    printf("%d\n", maxQ.Top());
                }

                return 0;
            }

            posted on 2012-09-02 14:25 yx 閱讀(1702) 評論(2)  編輯 收藏 引用 所屬分類: 數據結構

            評論

            # re: poj 2823 Sliding Window 單調隊列 2012-09-04 09:16 畢達哥拉斯半圓

            問個問題,如果窗口的長度變的,復雜度該如何分析呢?  回復  更多評論   

            # re: poj 2823 Sliding Window 單調隊列 2012-09-04 16:48 遠行

            @畢達哥拉斯半圓
            總的應該還是O(n),還是用聚集分析的方法,所有元素就入一次隊列,
            最多出一次隊列,平攤到每個元素就是O(1)  回復  更多評論   

            <2012年7月>
            24252627282930
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            導航

            統計

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            欧美亚洲日本久久精品| 久久精品中文闷骚内射| 久久免费视频网站| 婷婷久久综合九色综合九七| 区久久AAA片69亚洲| 性做久久久久久久| 伊人久久免费视频| 午夜天堂av天堂久久久| 91精品国产91久久| 久久天堂AV综合合色蜜桃网| 久久久久久久久久久久久久| 国产精品99久久精品爆乳| 久久精品国产亚洲AV大全| 久久久网中文字幕| 久久99国产一区二区三区| 99久久99久久精品国产片| 久久国产欧美日韩精品| 久久夜色精品国产亚洲av| 99久久精品费精品国产一区二区 | 精品久久久久久久国产潘金莲| 久久久久亚洲AV成人片| 久久无码AV中文出轨人妻| 久久国产香蕉一区精品| 精品国产青草久久久久福利| 久久久精品2019免费观看| 亚洲精品无码久久久久久| 亚洲综合久久夜AV | 无码人妻久久一区二区三区免费丨 | 久久综合给久久狠狠97色| 久久天天躁狠狠躁夜夜不卡 | 久久亚洲中文字幕精品一区| 久久精品一区二区影院| 久久se精品一区二区影院 | 午夜人妻久久久久久久久| 99久久无色码中文字幕人妻| 精品伊人久久大线蕉色首页| 香蕉久久永久视频| 东方aⅴ免费观看久久av| 久久夜色精品国产噜噜亚洲AV| 久久棈精品久久久久久噜噜| 996久久国产精品线观看|