給定整數數組 nums,找出所有 **不重複** 的三元組 [a, b, c] 使 a + b + c = 0。
要求:a ≤ b ≤ c,結果集無重複三元組。
O(n log n)。nums[i] (i = 0..n-3)。i+1 .. n-1 區間雙指針 L, R 尋找 nums[L] + nums[R] = -nums[i]。if (i > 0 && nums[i] == nums[i-1]) continue;while (L < R && nums[L] == nums[L+1]) ++L; 同理 R。class Solution {
public List> threeSum(int[] nums) {
List> res = new ArrayList<>();
if (nums.length < 3) return res;
Arrays.sort(nums);
for (int i = 0; i < nums.length - 2; ++i) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // 跳過重複首元素
int target = -nums[i];
int L = i + 1, R = nums.length - 1;
while (L < R) {
int sum = nums[L] + nums[R];
if (sum == target) {
res.add(Arrays.asList(nums[i], nums[L], nums[R]));
++L; --R;
while (L < R && nums[L] == nums[L - 1]) ++L; // 去重 L
while (L < R && nums[R] == nums[R + 1]) --R; // 去重 R
} else if (sum < target) {
++L;
} else {
--R;
}
}
}
return res;
}
}
O(n^2) —— 排序 O(n log n) + 雙層循環 O(n^2)。O(1) (不計輸出) / O(k) (輸出列表)。nums = [-4, -1, -1, 0, 1, 2] i=0 (-4) target=4 L=1 R=5 sum=1 L++ i=1 (-1) target=1 L=2 R=5 sum=1 ✓ [-1,-1,2] L=3 R=4 sum=1 ✓ [-1,0,1] L=4 R=3 stop i=2 (-1) skip (nums[2]==nums[1]) i=3 (0) target=0 L=4 R=5 sum=3 R-- ... 結果:[[-1,-1,2], [-1,0,1]]
| 變體 | 調整點 |
|---|---|
| 3Sum Closest | 記錄最小 |sum-target|,無需去重 |
| 3Sum Smaller | 計數 sum |
| 4Sum | 外層雙循環固定前兩數,內層雙指針 |
| 含重複元素輸出所有索引組合 | 不去重,改用 HashMap 計數 |