给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。
样例
例1:
输入:[2,7,11,15]
输出:[]
例2:
输入:[-1,0,1,2,-1,-4]
输出:[[-1, 0, 1],[-1, -1, 2]]
注意事项
在三元组(a, b, c),要求a <= b <= c。
结果不能包含重复的三元组。
解题思路1:
public class Solution {
/**
* @param numbers: Give an array numbers of n integer
* @return: Find all unique triplets in the array which gives the sum of zero.
*/
public List<List<Integer>> threeSum(int[] numbers) {
// write your code here
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(numbers);
dfs(numbers, new ArrayList<Integer>(), res, 0);
return res;
}
private void dfs(int[] a, List<Integer> list, List<List<Integer>> res, int index){
if(list.size() == 3){
int tmp = 0;
for(int i=0; i<list.size(); i++)
tmp += list.get(i);
if(tmp == 0){
res.add(new ArrayList<Integer>(list));
}
return;
}
for(int i = index; i < a.length; i++){
if(i != index && a[i] == a[i-1])
continue;
list.add(a[i]);
dfs(a, list, res, i + 1);
list.remove(list.size() - 1);
}
}
}
二刷:
public class Solution {
/**
* @param numbers: Give an array numbers of n integer
* @return: Find all unique triplets in the array which gives the sum of zero.
*/
public List<List<Integer>> threeSum(int[] numbers) {
// write your code here
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(numbers);
dfs(numbers, new ArrayList<Integer>(), 0, res, 0);
return res;
}
private void dfs(int[] numbers, List<Integer> list, int sum, List<List<Integer>> res, int index){
if(list.size() == 3){
if(sum == 0)
res.add(new ArrayList<Integer>(list));
return;
}
for(int i=index; i<numbers.length; i++){
if(i != index && numbers[i] == numbers[i-1])
continue;
list.add(numbers[i]);
dfs(numbers, list, sum+numbers[i], res, i+1);
list.remove(list.size()-1);
}
}
}
解题思路2:
看到三数之和就想起可以利用两数之和,也就是先遍历元素k,然后在k之后寻找两数之和等于-nums[k]即可,所以可以对数组先排序,然后使用双指针的方式找到两数之和,时间复杂度O(nlogn)。
注意由于题目中不允许出现重复的结果,所以对这三个元素都需要去重,即遇到相同元素跳过。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
for(int k=0; k<nums.length-2; k++){
//剔除掉重复的k
if(k > 0 && nums[k] == nums[k-1])
continue;
//two sum
int target = -nums[k];
int i=k+1, j=nums.length-1;
while(i < j){
if(nums[i] + nums[j] == target){
List<Integer> temp = new ArrayList<>();
temp.add(nums[k]);
temp.add(nums[i]);
temp.add(nums[j]);
res.add(temp);
i++;
//剔除掉重复的i
while(i < j && nums[i] == nums[i-1])
i++;
j--;
//剔除掉重复的j
while(i < j && nums[j] == nums[j+1])
j--;
}else if(nums[i] + nums[j] < target)
i++;
else
j--;
}
}
return res;
}
}

本文介绍了解决三数之和问题的两种方法。一种是通过深度优先搜索(DFS)递归求解,另一种则是采用排序加双指针的技术来提高效率。在解决过程中,特别注意去除重复解的情况。
2997

被折叠的 条评论
为什么被折叠?



