给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
本题的难点在于如何去除重复解。
时间复杂度:O(n^2),数组排序O(NlogN),遍历数组 O(n),双指针遍历 O(n),总体 O(NlogN)+O(n)?O(n),O(n^2)
空间复杂度:O(1)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n=len(nums)
res=[]
if(not nums or n<3):
return []
nums.sort()
res=[]
for i in range(n):
if(nums[i]>0):
return res
if(i>0 and nums[i]==nums[i-1]):
continue
L=i+1
R=n-1
while(L<R):
if(nums[i]+nums[L]+nums[R]==0):
res.append([nums[i],nums[L],nums[R]])
while(L<R and nums[L]==nums[L+1]):
L=L+1
while(L<R and nums[R]==nums[R-1]):
R=R-1
L=L+1
R=R-1
elif(nums[i]+nums[L]+nums[R]>0):
R=R-1
else:
L=L+1
return res
class Solution {
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList();
int len = nums.length;
if(nums == null || len < 3) return ans;
Arrays.sort(nums); // 排序
for (int i = 0; i < len ; i++) {
if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
int L = i+1;
int R = len-1;
while(L < R){
int sum = nums[i] + nums[L] + nums[R];
if(sum == 0){
ans.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 < 0) L++;
else if (sum > 0) R--;
}
}
return ans;
}
}
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
if(nums.size() < 3) return res;
sort(nums.begin(),nums.end()); //先排序
for(vector<int>::iterator it = nums.begin(); it != nums.end()-2;){
int tmp = *it;
if(tmp > 0) break;
int target = 0 - tmp;
vector<int>::iterator left = it+1;
vector<int>::iterator right = nums.end()-1;
while(left < right){
if(*right < 0) break; //如果右边小于0,break
if(*left + *right < target){
int v= *left;
while(left != right && *left == v) left++; //跳过相等的元素
}else if(*left + *right > target){
int v= *right;
while(left != right && *right == v) right --;//跳过相等的元素
}else{
vector<int> tmp_res{tmp,*left,*right}; //保存结果
res.push_back(tmp_res);
int v= *left;
while(left != right && *left == v) left++;//跳过相等的元素
v= *right;
while(left != right && *right == v) right --;//跳过相等的元素
}
}
while(it != nums.end()-2 && *it == tmp) it++;//跳过相等的元素
}
return res;
}
};
原文:https://www.cnblogs.com/wwj99/p/12254960.html