• <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 閱讀(1688) 評論(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

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久综合伊人77777麻豆| 精品久久无码中文字幕| 日本精品久久久久久久久免费| 久久精品亚洲乱码伦伦中文 | 中文字幕人妻色偷偷久久| 99久久无色码中文字幕人妻| 91精品国产91久久久久福利| 久久人人超碰精品CAOPOREN | 国产精品一区二区久久精品无码| 久久天天躁狠狠躁夜夜av浪潮 | 日韩精品久久久久久久电影蜜臀| 99热都是精品久久久久久| 日韩人妻无码一区二区三区久久99 | 久久ZYZ资源站无码中文动漫| 国产高潮久久免费观看| 亚洲va国产va天堂va久久| 国产高潮久久免费观看| 欧美黑人又粗又大久久久| 无码任你躁久久久久久久| 久久免费视频网站| 无码人妻久久一区二区三区免费丨| 久久精品无码一区二区三区免费| 久久免费高清视频| 99久久婷婷免费国产综合精品| 久久婷婷五月综合色奶水99啪| 久久精品国产精品亚洲| 久久精品中文字幕久久| 国产99精品久久| 国产精品美女久久久m| 久久久久亚洲av无码专区| 久久婷婷五月综合97色一本一本 | 久久久久亚洲精品无码网址| 97精品国产97久久久久久免费| 国产精品久久影院| 99久久精品国产免看国产一区| 久久久久人妻一区精品色| 久久精品无码专区免费青青| 久久精品人成免费| 国内精品久久久久影院优| 久久精品国产亚洲沈樵| 丰满少妇人妻久久久久久4|