题目描述
给定一个整数数组,判断数组中是否存在三元组a, b, c使得a+b+c = 0,找出数组中所有不重复的三元组。
分析
最先想到的方法肯定是三重循环遍历,但是时间复杂度太高了,而且也不能解决重复问题。再进一步,如果把一个数固定,这个问题就变成了两数之和。但是如何保证三元组不重复呢?
如果我们能够保证a <= b <= c,且每个数在遍历时不能与之前的重复,那么三元组就是不重复的。
因此我们需要先将数组排序(Onlogn),然后循环遍历第一个数(On),寻找两数之和时跟之前一样,从两端往中间找,这个时间复杂度就也控制在了(On),整体复杂度就是(Onlogn)+(On)*(On) = On2。
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
List<List<Integer>> ans = new ArrayList<>();
if (n < 3) return ans;
Arrays.sort(nums);
for (int i=0; i<n-1; i++) {
if (nums[i] > 0) break;
if (i>0 && nums[i]==nums[i-1]) continue;
int target = -nums[i];
int l = i+1, r = n-1;
while (l < r) {
if (nums[l]+nums[r] == target) {
ans.add(Arrays.asList(nums[i], nums[l], nums[r]));
++l; --r;
//保证每个数都跟前一个不一样
while (l<r && nums[l]==nums[l-1]) ++l;
while (l<r && nums[r]==nums[r+1]) --r;
} else if (nums[l]+nums[r] > target) {
--r;
} else {
++l;//两数之和比目标值小,增大左值
}
}
}
return ans;
}
}