<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          每日一道 LeetCode (52):三數(shù)之和

          共 823字,需瀏覽 2分鐘

           ·

          2020-10-14 22:37

          ?

          每天 3 分鐘,走上算法的逆襲之路。

          ?

          前文合集

          每日一道 LeetCode 前文合集

          代碼倉庫

          GitHub:https://github.com/meteor1993/LeetCode

          Gitee:https://gitee.com/inwsy/LeetCode

          題目:三數(shù)之和

          難度:「中等」

          題目來源:https://leetcode-cn.com/problems/3sum/

          給你一個包含 n 個整數(shù)的數(shù)組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重復(fù)的三元組。

          注意:答案中不可以包含重復(fù)的三元組。

          示例:

          給定數(shù)組?nums?=?[-1,?0,?1,?2,?-1,?-4],

          滿足要求的三元組集合為:
          [
          ??[-1,?0,?1],
          ??[-1,?-1,?2]
          ]

          解題思路

          之前一段時間都在寫 JVM 和 Tomcat 的一系列相關(guān)的文章,刷力扣題就給空下了,今天開始接著撿起來做題。

          首先這道題我第一個反應(yīng)是套三個循環(huán),肯定做得出來,時間復(fù)雜度是 O(n^3) ,放在力扣里面,按照一貫的尿性結(jié)果肯定是超時,這個方案我現(xiàn)在都已經(jīng)懶得寫了(對,我現(xiàn)在就是這么飄),除了鍛煉下寫代碼的能力,對于算法好像沒啥提升。

          其他的方案又想不出來,沒辦法,只能去翻答案。

          答案上的思路就很有意思了,第一件事兒就是先給數(shù)組排序,把這個數(shù)組變成一個有序數(shù)組。

          三個數(shù)加起來結(jié)果要是 0 ,會有一種特殊情況就是 0 + 0 + 0 = 0 。

          刨除掉上面這種情況,那么肯定第一位是負(fù)數(shù),后面第二位只能比第一位大,第三位要比第二位大(這不是顯而易見嘛)。

          套上前面的特殊情況,那么會有一個確定的關(guān)系 a <= b <= c 。

          這個問題解到這里,還是沒有跳脫出來三重循環(huán),那么時間復(fù)雜度依然還是 O(n^3) ,這肯定不行,還需要繼續(xù)優(yōu)化。

          目標(biāo)放在把時間復(fù)雜度降低到 O(n^2) 上,那么就是兩重循環(huán)要搞定所有的事兒,最外層的循環(huán)也就是找 a 的那個循環(huán),這個肯定是無法避免的,能玩的滑頭也就只剩下第二重循環(huán)了,在找 b 和 c 的過程,想辦法找到內(nèi)在的聯(lián)系,在一次循環(huán)中,直接把 b 和 c 全都找出來。

          如果我們固定了 a 和 b ,那么只會有一個唯一的 c 來滿足 a + b + c = 0 。當(dāng)?shù)诙匮h(huán)往后再循環(huán)一個 b1 的時候,這時如果存在 a + b1 + c1 = 0 ,那么這個 c1 一定要比之前的 c 來的要小。

          這樣我們可以在第二重循環(huán)里面考慮一個雙指針的方案,一個數(shù)組從小到大排列,取 b 的時候我們從小到大取,取 c 的時候我們從大到小來取,這時,我們?nèi)?b 和 c 其實是并列在第二重里面的,這樣我們強行把三重循環(huán)降成了兩重循環(huán)。

          這里的 b 和 c 可以抽象成兩個指針,左指針和右指針,左指針每像右移動一位,右指針向左有可能移動 n 位,這和數(shù)組的元素有關(guān),最差情況下會達(dá)到移動 n 次,因此,時間復(fù)雜度也是 O(n) ,第一重循環(huán)還有一個 O(n) ,所以整體的時間復(fù)雜度會達(dá)到 O(n^2) 。

          代碼:

          public?List>?threeSum(int[]?nums)?{
          ????int?n?=?nums.length;
          ????Arrays.sort(nums);
          ????List>?ans?=?new?ArrayList<>();
          ????//?最外層循環(huán),迭代?a
          ????for?(int?a?=?0;?a?????????//?由于元素不能重復(fù),遇到相同的直接下次循環(huán)
          ????????if?(a?>?0?&&?nums[a]?==?nums[a?-?1])?{
          ????????????continue;
          ????????}
          ????????//?c?對應(yīng)的指針初始指向數(shù)組的最右端
          ????????int?c?=?n?-?1;
          ????????int?target?=?-nums[a];
          ????????//?迭代?b
          ????????for?(int?b?=?a?+?1;?b?????????????//?一樣先判斷是否和上次迭代的元素是否相同
          ????????????if?(b?>?a?+?1?&&?nums[b]?==?nums[b?-?1])?{
          ????????????????continue;
          ????????????}
          ????????????//?b?的位置在?c?的左側(cè)
          ????????????while?(b??target)?{
          ????????????????--c;
          ????????????}
          ????????????//?如果出現(xiàn)了指針重合,就可以退出循環(huán)了,說明沒找到對應(yīng)的?c
          ????????????if?(b?==?c)?{
          ????????????????break;
          ????????????}
          ????????????//?如果出現(xiàn)了?b?和?c?加起來等于?-a?,說明我們找到的最后的結(jié)果
          ????????????if?(nums[b]?+?nums[c]?==?target)?{
          ????????????????List?list?=?new?ArrayList<>();
          ????????????????list.add(nums[a]);
          ????????????????list.add(nums[b]);
          ????????????????list.add(nums[c]);
          ????????????????ans.add(list);
          ????????????}
          ????????}
          ????}
          ????return?ans;
          }
          ?

          不知道各位還記不記得之前兩數(shù)之和的解法,當(dāng)我們確定了 a 和 b 以后,最終尋找 c 的時候還可以把整個數(shù)組放在一個哈希表中,通過哈希表的特性來判斷當(dāng)前 c 是否存在,如果不存在,則進(jìn)入下一次循環(huán)。

          ?




          感謝閱讀



          瀏覽 28
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲 欧美 国产 另类 | 日韩精品国产无码 | 日韩一级电影在线 | 内射影视| 欧美三级视频 |