每周一道算法題(十一)

本周的算法題難度級(jí)別Medium,但我用了兩天閑散的時(shí)間也沒(méi)通過(guò),最后卡在了“超時(shí)”上留储,上網(wǎng)查了查,不得不欽佩大牛的想法果然牛逼,值得借鑒學(xué)習(xí)啊

題目:已知一個(gè)有n個(gè)整數(shù)的數(shù)組S曹鸠,找到所有和為0的三個(gè)數(shù)蘑志。(不允許輸出重復(fù)的解)

說(shuō)下我的思路累奈,暴力破解,把所有的組合一個(gè)一個(gè)找卖漫,找出復(fù)合要求的三個(gè)數(shù)記錄费尽,然后刪除重復(fù)的,最后剩下的就是答案羊始,需要注意的一個(gè)問(wèn)題就是關(guān)于內(nèi)存的旱幼,代碼的注釋我會(huì)寫(xiě)的詳細(xì)一些,把我遇到的坑都列出來(lái)突委,避免重復(fù)踩坑柏卤,還要說(shuō)的一點(diǎn)是這個(gè)代碼并沒(méi)有通過(guò)全部測(cè)試冬三,再倒數(shù)第二組的時(shí)候就超時(shí)了,把樣本考出來(lái)缘缚,在Xcode上運(yùn)行沒(méi)有問(wèn)題勾笆,樣本有3000個(gè)數(shù),大概有1W多個(gè)符合要求的集合桥滨,在網(wǎng)上運(yùn)行算法的時(shí)候大概找出約3000個(gè)集合就超時(shí)了窝爪,很無(wú)奈,如下圖:


結(jié)果

接下來(lái)看看代碼:

/**
 * Return an array of arrays of size *returnSize.將長(zhǎng)度返回給returnSize
 * Note: The returned array must be malloced, assume caller calls free().返回的數(shù)組需要自己開(kāi)辟內(nèi)存空間齐媒,不需要考慮釋放問(wèn)題
 */
int** threeSum(int* nums, int numsSize, int* returnSize) {
    //由于找不到好的容器蒲每,我就用鏈表了,也算復(fù)習(xí)一下
    struct Node {
        int data[3];
        struct Node *next;
    }node;
    int i,j,k;
    struct Node *head, *p, *pt;
    int len = 0;
    head = (struct Node *)malloc(sizeof(node));
    head->next = NULL;
    p = head;
    //將其所有的組合一個(gè)一個(gè)列舉出來(lái)喻括,找出符合要求的所有的組合
    for (i = 0; i < numsSize; i++) {
        for (j = i+1; j < numsSize; j++) {
            if (j == i) continue;
            for (k = j+1; k < numsSize; k++) {
                if (k == i || k == j) continue;
                if (nums[i] + nums[j] + nums[k] == 0) {
                    int x1 = nums[i],x2 = nums[j],x3 = nums[k],t;
                    //將找出的組合進(jìn)行排序
                    if(x1>x2) {t=x1;x1=x2;x2=t;}
                    if(x2>x3) {t=x2;x2=x3;x3=t;}
                    if(x1>x2) {t=x1;x1=x2;x2=t;}
                    //記錄長(zhǎng)度
                    len++;
                    //將排序好的組合通過(guò)鏈表記錄
                    pt = (struct Node *)malloc(sizeof(node));
                    pt->data[0] = x1;
                    pt->data[1] = x2;
                    pt->data[2] = x3;
                    pt->next = NULL;
                    p->next = pt;
                    p = pt;
                }
            }
        }
    }
    //刪除重復(fù)的組合
    p = head->next; 
    struct Node *pre;
    while(p != NULL) {
        pre = p;
        while(pre->next != NULL) {
            if(pre->next->data[0] == p->data[0] && pre->next->data[1] == p->data[1] && pre->next->data[2] == p->data[2]) {
                pt = pre->next; 
                pre->next = pt->next;   
                free(pt);
                len--;//記錄長(zhǎng)度
            }else pre = pre->next;
        }
        p = p->next;
    }
    //返回長(zhǎng)度
    *returnSize = len;
    //將最后的結(jié)果整理返回
    p = head->next;
    //開(kāi)辟一個(gè)二維指針邀杏,由于是指針,所有sizeof里面是int*而不是int唬血,寫(xiě)int會(huì)提示對(duì)齊問(wèn)題而報(bào)錯(cuò)
    int **returnPtr = malloc(sizeof(int*) *len);
    int x = 0;
    while (p != NULL) {
        int *arr = malloc(sizeof(int) *3);
        for (i = 0;i < 3;i++)
            arr[i] = p->data[i];
        returnPtr[x++] = arr;
        p = p->next;
    }
    return returnPtr;
}

好遺憾因?yàn)槌瑫r(shí)沒(méi)過(guò)望蜡,看了網(wǎng)上的思路,不禁拍手叫絕啊

/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
 void quickSort(int* nums,int first,int end){
    int temp,l,r;
    if(first>=end)return;
    temp=nums[first];
    l=first;r=end;
    while(l<r){
        while(l<r && nums[r]>=temp)r--;
        if(l<r)nums[l]=nums[r];
        while(l<r && nums[l]<=temp)l++;
        if(l<r)nums[r]=nums[l];
    }
    nums[l]=temp;
    quickSort(nums,first,l-1);
    quickSort(nums,l+1,end);
}

int** threeSum(int* nums, int numsSize, int* returnSize) {
    int i,sum,top=-1,begin,end;
    int** res=(int**)malloc(sizeof(int*)*(numsSize*(numsSize-1)*(numsSize-2))/6);
    if(numsSize<3){
        *returnSize=0;
        return res;
    }
    //將nums從小到大進(jìn)行排序
    quickSort(nums,0,numsSize-1);
    
    for(i=0;i<numsSize;i++){
        //從左到右(從小到大)取出一個(gè)負(fù)數(shù)
        if(nums[i]>0)break;
        if(i>0 && nums[i]==nums[i-1])continue;
        //分別找出比這個(gè)負(fù)數(shù)大的最大的數(shù)end和最小的數(shù)begin
        begin=i+1;end=numsSize-1;
        //最小的數(shù)begin比最大的數(shù)小end
        while(begin<end){
            sum=nums[i]+nums[begin]+nums[end];
            if(sum==0){
                //記錄長(zhǎng)度
                top++;
                res[top]=(int*)malloc(sizeof(int)*3);
                res[top][0]=nums[i];res[top][1]=nums[begin];res[top][2]=nums[end];
                begin++;end--;
                while(begin<end && nums[begin]==nums[begin-1])begin++;
                while(begin<end && nums[end]==nums[end+1])end--;
            }else if(sum>0) end--;//如果和大于0拷恨,則將最大的數(shù)縮小
            else begin++;//如果和小于0脖律,則將最小的數(shù)擴(kuò)大
        }
    }
    *returnSize=top+1;
    return res;
}

概括一下就是先將樣本數(shù)組從小到大排序,然后遍歷找出符合要求的集合進(jìn)行返回即可挑随,因?yàn)檫M(jìn)行了排序呢状您,所以避免了重復(fù)的問(wèn)題,也通過(guò)正負(fù)數(shù)才能得出0的條件進(jìn)行了剪枝兜挨,大大提高了效率膏孟,通過(guò)各語(yǔ)言的對(duì)比,C語(yǔ)言的效率還是遙遙領(lǐng)先拌汇,就是感覺(jué)不方便柒桑。。噪舀。

版權(quán)聲明:本文為 Crazy Steven 原創(chuàng)出品魁淳,歡迎轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)注明出處!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末与倡,一起剝皮案震驚了整個(gè)濱河市界逛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纺座,老刑警劉巖息拜,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡少欺,警方通過(guò)查閱死者的電腦和手機(jī)喳瓣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)赞别,“玉大人畏陕,你說(shuō)我怎么就攤上這事》绿希” “怎么了惠毁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)堤撵。 經(jīng)常有香客問(wèn)我仁讨,道長(zhǎng),這世上最難降的妖魔是什么实昨? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮盐固,結(jié)果婚禮上荒给,老公的妹妹穿的比我還像新娘。我一直安慰自己刁卜,他們只是感情好志电,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蛔趴,像睡著了一般挑辆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孝情,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天鱼蝉,我揣著相機(jī)與錄音,去河邊找鬼箫荡。 笑死魁亦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羔挡。 我是一名探鬼主播洁奈,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼绞灼!你這毒婦竟也來(lái)了利术?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤低矮,失蹤者是張志新(化名)和其女友劉穎印叁,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喉钢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年姆打,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肠虽。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡幔戏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出税课,到底是詐尸還是另有隱情闲延,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布韩玩,位于F島的核電站垒玲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏找颓。R本人自食惡果不足惜合愈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望击狮。 院中可真熱鬧佛析,春花似錦、人聲如沸彪蓬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)档冬。三九已至膘茎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間酷誓,已是汗流浹背披坏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呛牲,地道東北人刮萌。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像娘扩,于是被迫代替她去往敵國(guó)和親着茸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1琐旁、用C語(yǔ)言實(shí)現(xiàn)一個(gè)revert函數(shù)涮阔,它的功能是將輸入的字符串在原串上倒序后返回。 2灰殴、用C語(yǔ)言實(shí)現(xiàn)函數(shù)void ...
    希崽家的小哲閱讀 6,262評(píng)論 0 12
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法敬特,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法伟阔,異常的語(yǔ)法辣之,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,623評(píng)論 18 399
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 10,960評(píng)論 6 13
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)皱炉,斷路器怀估,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • 1. 為什么想要開(kāi)始寫(xiě)作多搀? 其實(shí),寫(xiě)作之于我并不是現(xiàn)在才開(kāi)始——從小學(xué)一年級(jí)我就開(kāi)始寫(xiě)日記了——那才應(yīng)該算我人生中...
    杰出小卡閱讀 177評(píng)論 1 2