题目描述
给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。 注意:
三元组(a、b、c)中的元素必须按非降序排列。(即a≤b≤c) 解集中不能包含重复的三元组。 例如,给定的数组 S = {-10 0 10
20 -10 -40},解集为(-10, 0, 10) (-10, -10, 20)
解题思路:三个数相加,可以转化为两个数相加的场景。解决这类数组问题,可以先对数组进行排序,这样相当于多了一个隐含条件。
遍历数组中的每个数据,然后使用双指针寻找其它数据中符合要求的两个数。这样就转换成了两个数相加的问题。
为了避免结果重复,需要注意以下两处:
- 对于固定的数据,如果后面有和前一个数据相等的值,则要跳过。
- 在找到一组结果后,要判断
left
处和left + 1
处是否相等,相等则就重复,应该使left++
import java.util.*;
public class Solution {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
Arrays.sort(num);
// 遍历每隔数,寻找其它两数和该数相加,转换位两数相加问题
for(int i = 0; i < num.length; i++) {
if (i == 0 || num[i] != num[i - 1]) { // 避免重复
int left = i + 1;
int right = num.length - 1;
while (left < right) {
while (left < right && num[i] + num[left] + num[right] > 0){
right--;
}
if (left < right && num[i] + num[left] + num[right] == 0) {
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(num[i]);
temp.add(num[left]);
temp.add(num[right]);
res.add(temp);
int curLeft = num[left];
while (left < right && num[left] == curLeft) left++; // 去掉重复的
} else {
left++;
}
}
}
}
return res;
}
}