3Sum——LeetCode

  • Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
    Note: The solution set must not contain duplicate triplets.
    從給定的數(shù)組中找到所有和為0的3元組。并且兩兩三元組中的數(shù)字不可相同。
For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

一、暴力破解:

  • 技巧:既然要得到所有可能的三元組,三重for循環(huán)即可,注意如何寫(xiě)三重for循環(huán)。
        for (int i = 0; i < len; ++i)
            for (int j = i + 1; j < len; ++j)
                for (int k = j + 1; k < len; ++k)
  • 代碼如下,LeetCode理所當(dāng)然的超時(shí)了:
    public static List<List<Integer>> fourSum(int[] nums, int target) 
    {
        int len = nums.length;
        if (nums == null || nums.length < 3 )
            return new ArrayList<List<Integer>>();

        List<Integer> ns = null;
        HashSet<List<Integer>> set = new HashSet<>();

        //進(jìn)行暴力搜索,嘗試所有的三人組
        for (int i = 0; i < len; ++i)
        {
            for (int j = i + 1; j < len; ++j)
            {
                for (int k = j + 1; k < len; ++k)
                {
                    //filter the sum not equal target
                    if (nums[i] + nums[j] + nums[k] != target)
                    {
                        continue;
                    }

                    ns = new ArrayList<>();
                    ns.add(nums[i]);
                    ns.add(nums[j]);
                    ns.add(nums[k]);
                    //對(duì)三人組進(jìn)行排序,方便利用HashSet去重
                    Collections.sort(ns);
                    //去重
                    set.add(ns);
                }
            }
        }

        List<List<Integer>> lists = new ArrayList<>();
        for (List<Integer> s : set)
            lists.add(s);

        return lists;
    }

二、排序,固定一個(gè)指針,轉(zhuǎn)化為2Sum問(wèn)題

  • 第一步,對(duì)數(shù)組排序。
  • 第二步:
    分析1:對(duì)于元素 S[i] , 最后的答案可以分為兩種,包含 S[i] 的,和不包含 S[i] 的。當(dāng)包含 S[i] 的情況都找到后,后續(xù)就可以不用在考慮 S[i] 。對(duì)于 S[i] , l = i+1, r = len-1 。若 s[i] + S[l] + S[r] == 0, 則為原問(wèn)題的一個(gè)解。

當(dāng) S[i] + S[l] > -S[r] 時(shí),則 r--
當(dāng) S[i] + S[l] < -S[r] 時(shí),則 l++
當(dāng) S[i] + S[i] = -S[r] 時(shí), 表示是原問(wèn)題的一個(gè)解,則 l++, r--;

  • 第三步,性能優(yōu)化。同樣根據(jù)分析1,若 S[i] == S[i+1],可以跳過(guò)。
    public static List<List<Integer>> threeSumBySort(int[] nums) {
        int len = nums.length;
        List<List<Integer>> lists = new ArrayList<>();
        if (nums == null || nums.length < 3 )
            return lists;

        //sort
        Arrays.sort(nums);
        int low = 0;
        int high = 0;

        //1,2,3,4(固定指針從index = 2 開(kāi)始)
        for (int i = 0; i < len - 2; ++i)
        {
            //如果最小的數(shù)都大于0,break
            if (nums[i] > 0)
                break;

            //優(yōu)化,去重
            if (i > 0)
            {
                if (nums[i] == nums[i -1])
                    continue;
            }
            low = i + 1;
            high = len - 1;
            while (low < high)
            {
                //優(yōu)化,去重
                if (low > i + 1)
                {
                    if (nums[low] == nums[low - 1])
                    {
                        ++low;
                        continue;
                    }
                }
                //優(yōu)化,去重
                if (high < len - 1)
                {
                    if (nums[high] == nums[high + 1])
                    {
                        --high;
                        continue;
                    }
                }

                if (nums[i] + nums[low] + nums[high] == 0)
                {
                    lists.add(Arrays.asList(nums[i], nums[low], nums[high]));
                    ++low;
                    --high;
                }else if (nums[i] + nums[low] + nums[high] < 0) {
                    //如果小于0,則low index右移
                    ++low;
                }else {
                    //如果大于0,則high index左移
                    --high;
                }
            }
        }
        return lists;
    }

https://github.com/yuanoOo/Algorithm/tree/master/LeetCode

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,927評(píng)論 0 33
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 12,446評(píng)論 6 13
  • 前段時(shí)間,與朋友小醉一場(chǎng)。次日起床,腦袋里如同灌了鉛,昏昏沉沉。接連幾次,都是如此。這在之前從未有過(guò)。以前甭管...
    賓格子閱讀 508評(píng)論 0 0
  • 交接工作時(shí)盡量細(xì)致,方便接下來(lái)的工作順利進(jìn)行。 如手術(shù)的動(dòng)物我會(huì)盡量吧品種,體重,性別,手術(shù)時(shí)間,手術(shù)類(lèi)別,手術(shù)醫(yī)...
    姜雷_24b1閱讀 257評(píng)論 0 0

友情鏈接更多精彩內(nèi)容