給定一個包含 n 個整數的數組 S,判斷是否存在三個元素 a、b、c,使得 a + b + c = 0?找出所有滿足條件且不重複的三元組。
注意事項:
範例:
輸入:S = {-1, 0, 1, 2, -1, -4}
輸出:(-1, 0, 1) 和 (-1, -1, 2)
這是一個經典的三數之和問題。最直觀的暴力解法需要三層循環,時間複雜度為 O(n³),對於大數據會超時。優化的核心思路是:
/*********************************
* 日期:2014-01-18
* 作者:SJF0115
* 題號: 3Sum
* 來源:https://oj.leetcode.com/problems/3sum/
* 結果:AC
**********************************/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int>> triplets;
int len = num.size();
if (len < 3) return triplets;
// 排序
sort(num.begin(), num.end());
for (int i = 0; i < len - 2; i++) {
// 跳過重複元素
if (i != 0 && num[i] == num[i-1]) continue;
int target = -num[i];
int left = i + 1;
int right = len - 1;
while (left < right) {
int curSum = num[left] + num[right];
if (target == curSum) {
// 找到有效三元組
triplets.push_back({num[i], num[left], num[right]});
// 跳過重複元素
while (left < right && num[left] == num[left + 1]) left++;
while (left < right && num[right] == num[right - 1]) right--;
left++;
right--;
} else if (target > curSum) {
// 和太小,左指針右移
while (left < right && num[left] == num[left + 1]) left++;
left++;
} else {
// 和太大,右指針左移
while (left < right && num[right] == num[right - 1]) right--;
right--;
}
}
}
return triplets;
}
};
int main() {
vector<int> vec = {-2, 0, 0, 2, 2};
Solution solution;
vector<vector<int>> result = solution.threeSum(vec);
for (const auto& triplet : result) {
for (int val : triplet) {
printf("%d ", val);
}
printf("\n");
}
return 0;
}
輸入:[-2, 0, 0, 2, 2] 預期輸出:[[-2, 0, 2]]