maxgap 問題

<center>最大間隙問題

1.問題描述

? ?給定n個(gè)實(shí)數(shù)x_1,x_2 ,x_3 \cdots x_n,求這n個(gè)數(shù)在實(shí)數(shù)軸上相鄰2個(gè)數(shù)之間的最大間隙,假設(shè)對(duì)任何實(shí)數(shù)的向下取整運(yùn)算耗時(shí)O(1)涮总,設(shè)計(jì)一個(gè)線性時(shí)間算法解題胸囱。(數(shù)據(jù)的輸入由input.txt文件中讀得,算出的結(jié)果存到output.txt文件中瀑梗。)

1.1 題目分析

  • 問題求相鄰的最大間距烹笔,輸入又是無序的,如若先進(jìn)行排序抛丽,則排序的復(fù)雜度最少是O(nlogn),不滿足線性時(shí)間復(fù)雜度要求谤职。所以只能另想他法。
  • 問題聯(lián)想到組合數(shù)學(xué)中的插板問題亿鲜,將數(shù)字序列的上界和下界看成等差數(shù)列的首項(xiàng)和末項(xiàng)允蜈,每個(gè)公差的間距看成一個(gè)容器,根據(jù)等差數(shù)列的通項(xiàng)公式將每個(gè)數(shù)字放到容器中去蒿柳。a_n = a_1 +(n-1)d,所以數(shù)字散落在第0 \sim n-1個(gè)容器里陷寝。去除最小值,還剩下n-1個(gè)數(shù)字其馏,分布在n個(gè)容器里凤跑,遍歷容器至少有個(gè)空容器,有空的存在說明有大間距存在叛复。

1.2 想法可行性分析

??按照等差數(shù)列的通項(xiàng)公式(m-1)= \frac{a_m- a_1}3exttz7 仔引,這樣就可以求出任意數(shù)據(jù)a_m所在的位置\{(m-1) \subset \{ 0,1,2 \cdots n-1 \}\}。我們構(gòu)建n個(gè)相鄰容器褐奥,每個(gè)容器的寬度是公差d咖耘,第一個(gè)容器的起點(diǎn)是給定數(shù)字序列的最小值,第n個(gè)容器的起點(diǎn)是這個(gè)數(shù)字序列的最大值撬码。

容器1 容器2 \cdots \cdots 容器n
min \sim min+d - 1 min+d\sim min+2d -1 \cdots \cdots min+(n-1)d \sim min+nd -1

??當(dāng)把除去最小值之外的所有數(shù)字按照等差公式放入到相應(yīng)容器中時(shí)儿倒,由于有n-1個(gè)數(shù)字,而容器卻有n個(gè)呜笑,必然存在至少有一個(gè)容器為空夫否。那么問題就轉(zhuǎn)換為在遍歷n個(gè)容器找尋其中最長(zhǎng)連續(xù)為空的容器。

2. 解題過程描述

2.1. 數(shù)據(jù)結(jié)構(gòu)

??要實(shí)現(xiàn)上面的想法叫胁,需要借助于數(shù)據(jù)結(jié)構(gòu)凰慈。需要構(gòu)建容器類,其中包括的成員變量包括:容器中數(shù)字的數(shù)量驼鹅,容器中數(shù)字的最大值微谓、最小值森篷。類中的方法最主要的就是放置數(shù)字到容器中,該方法需要完成的工作包括:數(shù)字的數(shù)量+1豺型;驗(yàn)證新放置的數(shù)字是否超過目前容器中數(shù)字的最值界限仲智,若有,則更新最值姻氨。

#include <iostream>
#include <vector>
#include <math.h>
//抽屜類中包括元素個(gè)數(shù)钓辆,上界,下界哼绑,也可以有上下界索引
template<typename T>
class maxGap{
    private:
        int m_elemCount;
        T m_high;
        T m_low;

    public:
        maxGap():m_elemCount(0)
                 ,m_high(0.0)
                 ,m_low(0.0){}
        const T getHigh() const {return m_high;}
        const T getLow() const {return m_low;}
        const int getCount() const {return m_elemCount;}
        
        void insertElem(T elem){
            if(m_elemCount == 0){
                m_low = elem;
                m_high = elem;
            }
            else if(elem > m_high)
                m_high = elem;
            else if(elem < m_low)
                m_low = elem;
            m_elemCount ++ ;
        }
        
        
};

2.2. 算法描述及復(fù)雜度分析

??題干中要求時(shí)間的復(fù)雜度是線性的O(n)岩馍,下面我們來闡述算法流程和分析其時(shí)間復(fù)雜度。算法過程中主要的步驟包括:讀取文件抖韩,截取數(shù)字蛀恩,放置數(shù)字到容器,遍歷容器找到最大間隙茂浮。

template<typename T>
T solveMaxGap(std::vector<T> arr){
    int len = arr.size();
    T max = getmax(arr);
    std::cout<<"max:"<<max<<std::endl;
    T min = getmin(arr);
    std::cout<<"min:"<<min<<std::endl;
    T dimen = (max - min)/(len - 1);
    std::cout<<"dimen:"<<dimen<<std::endl;
    T temp_high = arr[0] - arr[0];
    T maxgap = 0;
    T tempgap = 0;
    int zeroPos = 0;
    int zeroCount = 0;
    maxGap<T> temp;
    std::vector< maxGap<T> > container(100,temp);
    container[len - 1].insertElem(max);//最大值放在len-1的位置双谆,非最值位于[0,len-2]
    //將元素放入桶中
    for(int i = 0 ;i < len; i++){
        if(arr[i] != max && arr[i] != min){
            int pos = floor((arr[i] - min )/ dimen);
    //      std::cout<<arr[i] <<"- "<< min<<"/"<<dimen <<":position:"<<pos<<std::endl;
            container[pos].insertElem(arr[i]);
        }
    }

    //遍歷桶席揽,找到最長(zhǎng)的連續(xù)空桶顽馋,或最大間隙
    for(int i = 0;i < len ; i ++){
       if(container[i].getCount() == 0)
       {
           zeroPos = I;
           zeroCount ++;
       }
       else 
       {
           if(zeroCount == 0)
               continue;
           else{
               if(zeroPos - zeroCount < 0 ){
                   tempgap = container[zeroPos + 1].getLow() - min;
                   maxgap = (maxgap > tempgap)?maxgap:tempgap;               
               }

               else{
                   tempgap = container[zeroPos + 1].getLow() - container[zeroPos - zeroCount].getHigh();
                   //std::cout<<"tempgap : "<<tempgap<<std::endl;
                   maxgap = (maxgap > tempgap)?maxgap:tempgap;               
                   zeroCount = 0;
                   zeroPos = 0;
               }
           }

       }
    }
    return maxgap;

}

??程序中所有的循環(huán)都不存在嵌套,只存在遍歷線性容器幌羞,時(shí)間復(fù)雜度為O(n)寸谜,程序滿足題目要求。

2.3. 算法結(jié)果驗(yàn)證

result.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末属桦,一起剝皮案震驚了整個(gè)濱河市熊痴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌聂宾,老刑警劉巖果善,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異系谐,居然都是意外死亡巾陕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門纪他,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鄙煤,“玉大人,你說我怎么就攤上這事止喷」堇啵” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵弹谁,是天一觀的道長(zhǎng)乾巧。 經(jīng)常有香客問我,道長(zhǎng)预愤,這世上最難降的妖魔是什么沟于? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮植康,結(jié)果婚禮上旷太,老公的妹妹穿的比我還像新娘。我一直安慰自己销睁,他們只是感情好供璧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冻记,像睡著了一般睡毒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冗栗,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天演顾,我揣著相機(jī)與錄音,去河邊找鬼隅居。 笑死钠至,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胎源。 我是一名探鬼主播棉钧,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼涕蚤!你這毒婦竟也來了宪卿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赞季,失蹤者是張志新(化名)和其女友劉穎愧捕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體申钩,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡次绘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撒遣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邮偎。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖义黎,靈堂內(nèi)的尸體忽然破棺而出禾进,到底是詐尸還是另有隱情,我是刑警寧澤廉涕,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布泻云,位于F島的核電站艇拍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宠纯。R本人自食惡果不足惜卸夕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婆瓜。 院中可真熱鬧快集,春花似錦、人聲如沸廉白。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)猴蹂。三九已至院溺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晕讲,已是汗流浹背覆获。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瓢省,地道東北人弄息。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像勤婚,于是被迫代替她去往敵國(guó)和親摹量。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354