• <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 閱讀(1694) 評論(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年9月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            導航

            統計

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            一级做a爰片久久毛片免费陪| 精品国产99久久久久久麻豆| 久久久久AV综合网成人| 日韩欧美亚洲综合久久| 人妻少妇久久中文字幕| 久久福利青草精品资源站| 久久精品无码一区二区三区免费| 色99久久久久高潮综合影院| 中文精品久久久久人妻不卡| 97久久久久人妻精品专区| 国产精品va久久久久久久| 伊人久久大香线蕉综合影院首页 | 久久天天躁狠狠躁夜夜96流白浆| 亚洲第一极品精品无码久久| 久久精品aⅴ无码中文字字幕不卡| 亚洲人成网亚洲欧洲无码久久| 国产午夜精品理论片久久 | 精品久久久久久无码不卡| 久久99久久成人免费播放| 91视频国产91久久久| 丁香狠狠色婷婷久久综合| 91精品国产高清91久久久久久| 久久99精品免费一区二区| 久久久久久久综合综合狠狠| 久久成人国产精品一区二区| 久久婷婷人人澡人人| 久久人妻无码中文字幕| 久久综合国产乱子伦精品免费| 亚洲综合熟女久久久30p| 久久精品aⅴ无码中文字字幕重口| 国产精品久久久久…| 久久国产一片免费观看| 久久久久亚洲AV综合波多野结衣 | 日日狠狠久久偷偷色综合0| 久久久91人妻无码精品蜜桃HD | 国产精品视频久久| 精品视频久久久久| 久久久久九九精品影院| 午夜精品久久久久久中宇| 久久久久久免费一区二区三区| 2021久久国自产拍精品|