iT邦幫忙

2025 iThome 鐵人賽

DAY 0
0
自我挑戰組

LeetCode 每日一題挑戰系列 第 13

鐵人賽 Day 13 — 3Sum

  • 分享至 

  • xImage
  •  

今天挑戰的是經典題目 3Sum。這題幾乎每個刷 LeetCode 的人都會遇到,因為它涵蓋了排序、雙指針,以及如何去除重複解的技巧。

題目核心

我們要從陣列裡找出所有 三個數字加起來等於 0 的組合,並且結果裡不能有重複的三元組。

範例:

[-1,0,1,2,-1,-4] → [[-1,-1,2], [-1,0,1]]

[0,1,1] → []

[0,0,0] → [[0,0,0]]

解題思路

排序:
先把陣列排序,這樣方便我們用雙指針移動。

固定一個數字,雙指針找另外兩個:
假設固定 nums[i],那我們就要找 [i+1, end] 之間兩個數字,讓它們的和等於 -nums[i]。

避免重複:

外層迴圈:若 nums[i] == nums[i-1],就跳過。

內層雙指針:找到一組解後,左右指針要跳過重複的數字。

Java 程式碼
import java.util.*;

class Solution {
public List<List> threeSum(int[] nums) {
List<List> res = new ArrayList<>();
Arrays.sort(nums);

    for (int i = 0; i < nums.length - 2; i++) {
        // 跳過重複的 i
        if (i > 0 && nums[i] == nums[i - 1]) continue;
        
        int left = i + 1, right = nums.length - 1;
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];
            
            if (sum == 0) {
                res.add(Arrays.asList(nums[i], nums[left], nums[right]));
                
                // 跳過重複的 left/right
                while (left < right && nums[left] == nums[left + 1]) left++;
                while (left < right && nums[right] == nums[right - 1]) right--;
                
                left++;
                right--;
            } else if (sum < 0) {
                left++;
            } else {
                right--;
            }
        }
    }
    return res;
}

}

https://ithelp.ithome.com.tw/upload/images/20250926/20169537HBZ6uIDChw.pnghttps://ithelp.ithome.com.tw/upload/images/20250926/20169537IQQFKiSxYJ.pnghttps://ithelp.ithome.com.tw/upload/images/20250926/20169537tg2JetPuHq.pnghttps://ithelp.ithome.com.tw/upload/images/20250926/20169537LhZzRNo4ZT.png

心得

這題算是「雙指針」的進階版。
一開始如果用三層迴圈,時間複雜度會到 O(n^3),完全會 TLE。
而利用排序 + 雙指針,時間就降到 O(n^2),這樣在 n <= 3000 的情況下就能過。

最麻煩的就是 去重複,不管是外層還是內層指針,都要小心跳過相同數字,否則答案會多一堆重複組合。


上一篇
鐵人賽 Day 12 — Longest Common Prefix
下一篇
第14天:3Sum Closest 題目心得
系列文
LeetCode 每日一題挑戰14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言