class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
if(n < 3){
return {};
}
vector<vector<int>>ans;
sort(nums.begin(),nums.end());
//枚举a
for(int i = 0; i < n; i++){
if(nums[0] > 0) return {};//排序后最小的元素都大于0,则找不到三数之和为0
if(i > 0 && nums[i] == nums[i-1]){//去重,不取重复的数
continue;
}
int target = -nums[i];
int k = n-1; // c 对应的指针初始指向数组的最右端
//枚举b
for(int j = i + 1; j < n; j++){
if(j > i+1 && nums[j] == nums[j-1]){//去重,不取重复的数
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while(k > j && nums[j] + nums[k] > target){//剩下两数之和过大,则减小第三个数
k--;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if(k == j){
break;
}
if(nums[j] + nums[k] == target){
ans.push_back({nums[i],nums[j],nums[k]});
}
}
}
return ans;
}
};
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>res;
sort(nums.begin(),nums.end());
for(int i = 0; i < nums.size(); i++){
// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if(nums[i] > 0){
return res;
}
//去重
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
int left = i+1;
int right = nums.size()-1;
while(left < right){
if(nums[i] + nums[left] + nums[right] > 0){
right--;
// while(left < right && nums[right + 1] == nums[right])right--;
}else if(nums[i] + nums[left] + nums[right] < 0){
left++;
// while(left < right && nums[left - 1] == nums[left])left++;
}else{
res.push_back(vector<int>{nums[i],nums[left],nums[right]});
//去重逻辑应该放到找到一个三元数组之后
while(left < right && nums[right - 1] == nums[right])right--;
while(left < right && nums[left + 1] == nums[left])left++;
right--;
left++;
}
}
}
return res;
}
};
go:
func threeSum(nums []int) [][]int {
sort.Ints(nums)
res := [][]int{}
for i := 0; i < len(nums)-2; i++{
n1 := nums[i]
if nums[i] > 0{
return res
}
if i > 0 && nums[i-1] == nums[i]{
continue
}
l,r := i + 1,len(nums) - 1
for l < r{
n2,n3 := nums[l],nums[r]
if n1+n2+n3 == 0{
res = append(res, []int{n1,n2,n3})
for l < r && nums[l] == n2{
l++
}
for l < r && nums[r] == n3{
r--
}
}else if n1+n2+n3 < 0{
l++
}else{
r--
}
}
}
return res
}