2021-03-22 Leetcode-15

15.三數(shù)之和

想了兩個(gè)方法。第一個(gè)超時(shí),第二個(gè)僥幸過關(guān)但是用時(shí)和內(nèi)存都消耗過多,以后再來改進(jìn)。

思路:

  1. 輸入數(shù)組長度小于3時(shí)肯定返回空List
  2. 三數(shù)相加為0會有如下幾種情況:
    2.1 三個(gè)0
    2.2 兩負(fù)一正(兩負(fù)相同/兩負(fù)不同)
    2.3 一負(fù)一正加個(gè)零
    2.4 一負(fù)兩正(兩正相同/兩正不同)
    總共6個(gè)點(diǎn)
  3. 根據(jù)以上6個(gè)點(diǎn)進(jìn)行設(shè)計(jì)丰捷,得出List
  4. 去重:
    思路1:得出list后判斷是否在結(jié)果的list中有出現(xiàn)過
    思路2:在遍歷時(shí)根據(jù)從小到大進(jìn)行過濾
  5. 排序
    題目并沒有這樣的要求,但是如果提交時(shí)集合內(nèi)不是按照升序會判錯(cuò)寂汇。
    思路1:在一開始就進(jìn)行輸入的升序排列病往。遍歷時(shí)升序遍歷找出合適的List加入結(jié)果集合。最終的順序就是升序健无。
    思路2:使用鍵值對時(shí)荣恐,在完成集合之后重寫sort中的comparator。
/*執(zhí)行用時(shí):190 ms, 在所有 Java 提交中擊敗了10.89%的用戶
內(nèi)存消耗:44.1 MB, 在所有 Java 提交中擊敗了5.00%的用戶*/
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ll = new ArrayList<>();
        Map<Integer, Integer> negaMap= new HashMap<>();
        Map<Integer, Integer> posiMap= new HashMap<>();
        int zero = 0;
        int len = nums.length;
        if(len < 3)    return ll;
        for(int i = 0; i < len; i++){
            if(nums[i] < 0) {
                if(!negaMap.containsKey(nums[i])){
                    negaMap.put(nums[i],1);
                }else{
                    negaMap.put(nums[i], negaMap.get(nums[i]) + 1);
                }
            }
            if(nums[i] == 0) zero++;
            if(nums[i] > 0) {
                if(!posiMap.containsKey(nums[i])){
                    posiMap.put(nums[i],1);
                }else{
                    posiMap.put(nums[i], posiMap.get(nums[i]) + 1);
                }
            }
        }
        //3個(gè)0
        if(zero >= 3){
            List<Integer> l = new ArrayList<>();
            l.add(0);
            l.add(0);
            l.add(0);   
            ll.add(l);
        }
        if(negaMap.isEmpty() || posiMap.isEmpty())   return ll;
        for (Map.Entry<Integer, Integer> entry : negaMap.entrySet()){
            //2(相同)負(fù)數(shù)1正數(shù)
            if(entry.getValue() >= 2 && posiMap.containsKey(entry.getKey() * (-2))){
                List<Integer> l = new ArrayList<>();
                l.add(entry.getKey());
                l.add(entry.getKey());
                l.add(entry.getKey() * -2);
                ll.add(l);
            }
            if(posiMap.containsKey(entry.getKey() * (-1)) && zero > 0){
                //一正一負(fù)一零
                List<Integer> l = new ArrayList<>();
                l.add(entry.getKey());
                l.add(0);
                l.add(entry.getKey() * (-1));
                ll.add(l);
            }
            for(Map.Entry<Integer, Integer> entry1 : negaMap.entrySet()){
                //2不同負(fù)數(shù)累贤,1正數(shù)
                if(entry1.getKey() <= entry.getKey())   continue;
                if(posiMap.containsKey((entry1.getKey() + entry.getKey()) * (-1))){
                    List<Integer> l = new ArrayList<>();
                    l.add(entry.getKey());
                    l.add(entry1.getKey());
                    l.add((entry1.getKey() + entry.getKey()) * (-1));
                    ll.add(l);
                }
            }
        }
        for (Map.Entry<Integer, Integer> entry : posiMap.entrySet()){
            //2相同正1負(fù)
            if(entry.getValue() >= 2 && negaMap.containsKey(entry.getKey() * (-2))){
                List<Integer> l = new ArrayList<>();
                l.add(entry.getKey() * (-2));
                l.add(entry.getKey());
                l.add(entry.getKey());
                
                ll.add(l);
            }
            for(Map.Entry<Integer, Integer> entry1 :posiMap.entrySet()){
                if(entry1.getKey() <= entry.getKey())   continue;
                //2不同正1負(fù)
                if(negaMap.containsKey((entry1.getKey() + entry.getKey()) * (-1))){
                    List<Integer> l = new ArrayList<>();
                    l.add((entry1.getKey() + entry.getKey()) * (-1));
                    l.add(entry.getKey());
                    l.add(entry1.getKey());
                    
                    ll.add(l);
                }
            }
        }
        Collections.sort(ll, new Comparator<List<Integer>>(){
            public int compare(List<Integer> l1, List<Integer> l2){
                for(int i = 0; i < l1.size(); i++){
                    if(l1.get(i) > l2.get(i))       return 1;
                    else if(l1.get(i) < l2.get(i))  return -1;
                    else                            continue;
                }
                return 0;
            }
        });
        return ll;
    }
}

//超時(shí)
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ll = new ArrayList<>();
        //負(fù)數(shù)集合和整數(shù)集合
        List<Integer> negalist = new ArrayList<>();
        List<Integer> posilist = new ArrayList<>();
        //排序,最后不需要再進(jìn)行排序  
        Arrays.sort(nums);
        int negative_right=-1, positive_left=-1;
        //2負(fù)1正少漆,2正一負(fù)臼膏,一正一負(fù)一0,三個(gè)0
        for(int i = 0; i < len-1; i++){
            if(nums[i] == 0){
                nums0++;
            }
            if(nums[i] < 0 && nums[i+1]==0){
                negative_right = i;
            }else if(nums[i] == 0 && nums[i+1] >0){
                positive_left = i+1;
            }else if(nums[i] < 0 && nums[i+1] > 0){
                negative_right = i;
                positive_left = i+1;
            }
        }
        if(nums[len-1] == 0)    nums0++;
        //3個(gè)0
        if(nums0 >= 3){
            List<Integer> l = new ArrayList<>();
            l.add(0);
            l.add(0);
            l.add(0);   
            ll.add(l);
        }
        if(negative_right == -1 || positive_left == -1) return ll;
        for(int i = 0; i <= negative_right; i++){
            //i標(biāo)在正,k標(biāo)在負(fù),j標(biāo)正0負(fù)都有
            for(int j=len-1; j >= positive_left; j--){
                for(int k= i + 1; k < j; k++){
                    if(nums[i] + nums[j] + nums[k] == 0){
                        List<Integer> l = new ArrayList<>();
                        l.add(nums[i]);
                        l.add(nums[k]);
                        l.add(nums[j]);
                        
                        if(!ListContains(l, ll)){
                            ll.add(l);
                        }
                        break;
                    }
                }
            }
        }
        return ll;
    }
    public boolean ListContains(List<Integer> l1, List<List<Integer>> l2){
    //判斷結(jié)果集合中是否有List示损,去重
        for(List<Integer> l : l2){
            if(ListEqual(l, l1))    return true;
        }
        return false;
    }
    public boolean ListEqual(List<Integer> l1, List<Integer> l2){
    //判斷兩個(gè)List是否相等
        if(l1.size() != l2.size()){
            return false;
        }
        for(int i=0; i < l1.size(); i++){
            if(l1.get(i) != l2.get(i)){
                return false;
            }
        }
        return true;
    }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渗磅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌始鱼,老刑警劉巖仔掸,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異医清,居然都是意外死亡起暮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門会烙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來负懦,“玉大人,你說我怎么就攤上這事柏腻≈嚼鳎” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵五嫂,是天一觀的道長颗品。 經(jīng)常有香客問我,道長沃缘,這世上最難降的妖魔是什么躯枢? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮孩灯,結(jié)果婚禮上闺金,老公的妹妹穿的比我還像新娘。我一直安慰自己峰档,他們只是感情好败匹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著讥巡,像睡著了一般掀亩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上欢顷,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天槽棍,我揣著相機(jī)與錄音,去河邊找鬼抬驴。 笑死炼七,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的布持。 我是一名探鬼主播豌拙,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼题暖!你這毒婦竟也來了按傅?” 一聲冷哼從身側(cè)響起捉超,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唯绍,沒想到半個(gè)月后拼岳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡况芒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年惜纸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牛柒。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堪簿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出皮壁,到底是詐尸還是另有隱情椭更,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布蛾魄,位于F島的核電站虑瀑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏滴须。R本人自食惡果不足惜舌狗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扔水。 院中可真熱鬧痛侍,春花似錦、人聲如沸魔市。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽待德。三九已至君丁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間将宪,已是汗流浹背绘闷。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留较坛,地道東北人印蔗。 一個(gè)月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像丑勤,于是被迫代替她去往敵國和親喻鳄。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

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