算法解題記錄——TwoSum(leetCode#1-easy)

本文由作者三汪首發(fā)于簡(jiǎn)書。
歷史解題記錄已同步更新github.

題目

Problem Description
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

題目分析

題意是讓我們返回給定數(shù)組中和為目標(biāo)值的兩個(gè)元素的下標(biāo)。同時(shí)限定每個(gè)輸入都將只有一個(gè)解完箩,并且每個(gè)元素我們只能使用一次。

代碼和思路

A.原始版本

看到這個(gè)題目房揭。作為小白的我當(dāng)然是不假思索地用了窮舉法箭阶。時(shí)間復(fù)雜度O(n^2)。

好在這種粗暴的解決方案沒(méi)有像后來(lái)看到的別人說(shuō)的那樣因?yàn)闀r(shí)間復(fù)雜度太高而被leetCode拒收谚殊,
還勝過(guò)了30.2%的Java Solution丧鸯。
我認(rèn)為原因大概是因?yàn)槲矣昧藗€(gè)小聰明讓內(nèi)部循環(huán)的j=i+1而不是j=0。時(shí)
間復(fù)雜度雖然沒(méi)變嫩絮,但是實(shí)際上還是要更好一點(diǎn)的丛肢。
(如果你跟我一樣是小白,深思熟慮后還是不理解為什么這樣做剿干,給我留言呀蜂怎。我來(lái)告訴你~)

1.0版本代碼如下:

    /**
     * 
     * <p>
     * Description:我自己的第一個(gè)解決方案<br />
     * 耗時(shí):39ms
     * </p>
     * @author wugy
     * @version 0.1 2017年12月4日
     * @param nums
     * @param target
     * @return
     * int[]
     */
    private int[] twoSum_1_0(int[] nums, int target) {
        
        int[] indices =new int[2];
        for (int i = 0; i < nums.length; i++) {
            for (int j = i+1; j < nums.length; j++) {
                if (nums[i]+nums[j]==target) {
                    indices[0]=i;
                    indices[1]=j;
                    return indices;
                }
            }
        }
        return null;
       
    }

B.改進(jìn)版本

有思考才有進(jìn)步嘛。
我點(diǎn)進(jìn)了leetCode上提供的用時(shí)最少(3ms)的solution研究了一下置尔,又綜合了網(wǎng)上一些朋友的心得杠步。
(研究這道題斷斷續(xù)續(xù)的,時(shí)間跨度比較久榜轿。因此無(wú)法給出參考鏈接幽歼。只能在心里感謝一下這些朋友了)

我認(rèn)為對(duì)這個(gè)問(wèn)題最好的解決方式是使用Map來(lái)儲(chǔ)存key-value。
key是nums[]的元素谬盐,value是nums[]對(duì)應(yīng)元素的下標(biāo)甸私。
從代碼量和時(shí)間復(fù)雜度來(lái)說(shuō),這種解決思路應(yīng)該是最優(yōu)雅的飞傀。

代碼如下:

    /**
     * 
     * <p>
     * Description:研究過(guò)別人代碼以后的第二個(gè)改進(jìn)版本<br />
     * 耗時(shí):9ms
     * </p>
     * @author wugy
     * @version 1.1 2017年12月6日
     * @param nums
     * @param target
     * @return
     * int[]
     */
    private int[] twoSum_1_2(int[] nums, int target){
        Map<Integer,Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {     
            int diff = target-nums[i];
            if (map.containsKey(diff)) {
                return new int[]{map.get(diff),i};
            }
            map.put(nums[i], i);
        }
        return null;
        
    }

其實(shí)說(shuō)實(shí)話我不知道為什么這個(gè)1.2版本的改進(jìn)方案在leetCode上只能跑出9ms的成績(jī)皇型。
因?yàn)槲铱吹?ms的Sample Solution和我這個(gè)版本的改進(jìn)實(shí)際上是基本相同的诬烹。
leetCode告訴我我的這個(gè)版本打敗了59.65%的Java Solution。

至于其他用時(shí)比較少的Solution弃鸦,我覺(jué)得就比較扯了绞吁。
下面讓我來(lái)告訴你扯在哪里。

C.LeetCode上用時(shí)最少的Java Solution

直接來(lái)分析這個(gè)用時(shí)3ms的solution吧

    /**
     * 
     * <p>
     * Description:截至此刻leetCode上的最優(yōu)解<br />
     * 耗時(shí):3ms<br />
     * </p>
     * 已發(fā)現(xiàn)2個(gè)無(wú)法通過(guò)的TestCase:<br />
     * 1.Input:[2222222,2222222],4444444;Output:[0,1]<br />
     * 2.Input:[-9,4,9,90],0;Output:[0,2]<br />
     * @deprecated
     * @version 0.1 2017年12月4日
     * @param nums
     * @param target
     * @return
     * int[]
     */
    private int[] bestTwoSum(int[] nums, int target) {
        int[] map = new int[20050];//完全無(wú)法理解為什么數(shù)組長(zhǎng)度為20050寡键。這種做法如果傳入的數(shù)組中有比20050更大的值就掛了。已向leetCode提交TestCase
        int size = 4;
        for (int i = 0; i < nums.length; i++) {
            map[nums[i] + size] = (i + 1);
            int diff = target - nums[i + 1] + size;
            if (diff < 0) continue;
            int d = map[diff];
            if (d > 0)
                return new int[]{d - 1, i + 1};
        }
        return null;
    }

拿到這個(gè)solution的時(shí)候我是懵逼的雪隧。
因?yàn)椴恢罏槭裁磎ap[]數(shù)組定義成了20050的大小西轩,也不知道為什么要定義一個(gè)size=4。
結(jié)合自己的理解對(duì)這種進(jìn)行了重寫以后脑沿。我慢慢地理解了這個(gè)solution藕畔。

因?yàn)檫@個(gè)solution純屬扯淡。

數(shù)組定義成20050的大小應(yīng)該是因?yàn)橐延蠺estCase中nums[]元素沒(méi)有大于20050的庄拇。
size=4是因?yàn)門estCase中元素為負(fù)的的值最小為-3或-4注服。
有了size,后面代碼中if (diff < 0) continue;的這個(gè)判斷才有意義。也因此進(jìn)一步減少了耗時(shí)措近。
在上面代碼注釋中溶弟,我給出了2個(gè)無(wú)法通過(guò)的TestCase。均已提交LeetCode瞭郑。

思考

其實(shí)辜御。如果能使用int[]數(shù)組來(lái)轉(zhuǎn)換元素值與下標(biāo),實(shí)際上是更友好的屈张。
而我們不這么做呢擒权。因?yàn)閕nt[]數(shù)組無(wú)法定義到足夠存放-2147483648到2147483647的所有int數(shù)值,會(huì)OutOfMemory阁谆。
因此只能使用HashMap來(lái)代替它碳抄。


以上。
希望我的文章對(duì)你能有所幫助场绿。
我不能保證文中所有說(shuō)法的百分百正確剖效,
但我能保證它們都是我的理解和感悟以及拒絕直接復(fù)制黏貼(確實(shí)需要引用的部分我會(huì)附上源地址)。
有什么意見(jiàn)焰盗、見(jiàn)解或疑惑贱鄙,歡迎留言討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末姨谷,一起剝皮案震驚了整個(gè)濱河市逗宁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梦湘,老刑警劉巖瞎颗,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件件甥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡哼拔,警方通過(guò)查閱死者的電腦和手機(jī)引有,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)倦逐,“玉大人譬正,你說(shuō)我怎么就攤上這事∶世眩” “怎么了曾我?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)健民。 經(jīng)常有香客問(wèn)我抒巢,道長(zhǎng),這世上最難降的妖魔是什么秉犹? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任蛉谜,我火速辦了婚禮,結(jié)果婚禮上崇堵,老公的妹妹穿的比我還像新娘型诚。我一直安慰自己,他們只是感情好鸳劳,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布俺驶。 她就那樣靜靜地躺著,像睡著了一般棍辕。 火紅的嫁衣襯著肌膚如雪暮现。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天楚昭,我揣著相機(jī)與錄音栖袋,去河邊找鬼。 笑死抚太,一個(gè)胖子當(dāng)著我的面吹牛塘幅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播尿贫,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼电媳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了庆亡?” 一聲冷哼從身側(cè)響起匾乓,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎又谋,沒(méi)想到半個(gè)月后拼缝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娱局,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年咧七,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衰齐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡继阻,死狀恐怖耻涛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瘟檩,我是刑警寧澤抹缕,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站芒帕,受9級(jí)特大地震影響歉嗓,放射性物質(zhì)發(fā)生泄漏丰介。R本人自食惡果不足惜背蟆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哮幢。 院中可真熱鬧带膀,春花似錦、人聲如沸橙垢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柜某。三九已至嗽元,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喂击,已是汗流浹背剂癌。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翰绊,地道東北人佩谷。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像监嗜,于是被迫代替她去往敵國(guó)和親谐檀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)裁奇。 張土汪:刷leetcod...
    土汪閱讀 12,724評(píng)論 0 33
  • leetcode刷題記錄本文記錄一下leetcode刷題記錄桐猬,記錄一下自己的解法和心得。 LeetCode Two...
    EarthChen閱讀 3,436評(píng)論 0 6
  • 轉(zhuǎn)載自:https://egoistk.github.io/2016/09/10/Java%E6%8E%92%E5...
    chad_it閱讀 978評(píng)論 0 18
  • LeetCode 刷題隨手記 - 第一部分 前 256 題(非會(huì)員)刽肠,僅算法題课幕,的吐槽 https://leetc...
    蕾娜漢默閱讀 17,692評(píng)論 2 36
  • 從今天開始厦坛,寫一下我在刷 LeetCode 時(shí)的心得體會(huì),包括自己的思路和別人的優(yōu)秀思路乍惊,歡迎各種監(jiān)督岸沤铡! ...
    秋名山菜車手閱讀 936評(píng)論 0 1