給定整數數組 nums,找出所有不重複的三元組 [a, b, c],滿足 a + b + c = 0,且 a ≤ b ≤ c。輸出三元組列表,順序不限。
for (i=0; i
❌ 超時,大量重複計算。
Arrays.sort(nums),保證 a ≤ b ≤ c 自然滿足 i < j < k。nums[i],在 i+1 ... n-1 區間雙指針 L,R 尋找 nums[L]+nums[R] = -nums[i]。i>0 && nums[i]==nums[i-1] continue;找到解後 while(L 同理 R--。 public List> threeSum(int[] nums) {
Arrays.sort(nums);
List> res = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i-1]) continue; // 跳過重複首元素
if (nums[i] > 0) break; // 排序後首元素>0,後續全>0,不可能和為0
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]));
while (L < R && nums[L] == nums[L+1]) L++;
while (L < R && nums[R] == nums[R-1]) R--;
L++; R--;
} else if (sum < target) L++;
else R--;
}
}
return res;
}
✅ 時間 O(n²),空間 O(1)(不計輸出),代碼簡潔,業界標準解法。
構建 HashMap 記錄每個值的所有下標(已排序)。固定 i,j 計算 need = -(nums[i]+nums[j]),查 Map 中是否存在 need 且下標 > j。去重用 Set 記錄 "a#b"。雖同為 O(n²),但常數因子大、代碼複雜,**不推薦生產使用**,僅作為思維拓展。
| 優化點 | 作用 |
|---|---|
| 排序 | 天然滿足 a≤b≤c,支持雙指針、去重、提前剪枝 |
| 首元素 > 0 剪枝 | 後續全正數,直接 break |
| 首元素去重 | i>0 && nums[i]==nums[i-1] 跳過 |
| 雙指針移動 | 單調性保證不遺漏、不重複 |
| 找到解後雙指針去重 | 跳過相同值,避免重複三元組 |
count += R-L。