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

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久se精品一区二区影院| 精品久久久久一区二区三区| 国产精品久久久久aaaa| 精品午夜久久福利大片| 免费精品久久久久久中文字幕| 老司机午夜网站国内精品久久久久久久久 | 久久精品a亚洲国产v高清不卡| 精品久久久久久中文字幕人妻最新| 99久久亚洲综合精品成人| 66精品综合久久久久久久| 久久人人爽人人澡人人高潮AV | 热久久这里只有精品| 少妇熟女久久综合网色欲| 精品国产VA久久久久久久冰| 久久久久久久久久免免费精品 | 亚洲中文精品久久久久久不卡| 久久免费视频观看| 日本亚洲色大成网站WWW久久| 国产精品九九九久久九九| 亚洲精品WWW久久久久久| 久久免费观看视频| 久久久九九有精品国产| 午夜精品久久久久久中宇| 久久夜色精品国产网站| 亚洲va久久久噜噜噜久久| 久久人人爽人人爽人人片AV东京热| 久久亚洲高清观看| 久久人人爽爽爽人久久久| 性色欲网站人妻丰满中文久久不卡| 久久综合久久性久99毛片| 久久精品国产国产精品四凭| 亚洲综合精品香蕉久久网97 | 久久亚洲精品成人无码网站| 品成人欧美大片久久国产欧美... 品成人欧美大片久久国产欧美 | 一本一道久久综合狠狠老| 欧美精品乱码99久久蜜桃| 狠狠色丁香久久婷婷综合_中 | 久久精品无码一区二区三区免费| 青青草原综合久久| 91久久精品视频| 久久久久国产一区二区三区|