• <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

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            国产一区二区精品久久岳| 久久91这里精品国产2020| 国产69精品久久久久99尤物| 国产精品毛片久久久久久久| 国产福利电影一区二区三区,免费久久久久久久精| 久久国产免费直播| 国产精品va久久久久久久| 精品国产婷婷久久久| 亚洲欧洲久久久精品| 99久久久久| 久久国产精品久久| 色婷婷综合久久久久中文一区二区| 精品视频久久久久| 思思久久好好热精品国产| 国产精品成人久久久久三级午夜电影| 久久露脸国产精品| 久久久精品久久久久特色影视| 97久久国产亚洲精品超碰热| 成人精品一区二区久久久| 狠狠色婷婷久久综合频道日韩 | 久久国产热精品波多野结衣AV| 武侠古典久久婷婷狼人伊人| 国产成人无码精品久久久免费 | 久久久久久狠狠丁香| 精品久久久久久久久中文字幕| 欧美激情精品久久久久久久| 国产高潮国产高潮久久久| 91精品国产乱码久久久久久| 亚洲精品tv久久久久| 久久99亚洲综合精品首页| 国产91久久精品一区二区| 亚洲精品国产字幕久久不卡| 久久精品人人做人人爽97 | 一本色综合网久久| 国产精品久久久久久久app| 99精品国产免费久久久久久下载| 久久国产精品一区二区| 国产情侣久久久久aⅴ免费| 久久亚洲私人国产精品| 欧洲人妻丰满av无码久久不卡| 精品熟女少妇AV免费久久|