先用了dfs来做,结果超时了,重新考虑题目的特点。
思路:可以先将数组排序,然后固定第一个数i,然后设定两个指针,一个从i+1开始,一个从num.length-1开始,判断这两个位置的数的和是否等于0-nums[i],如果大于目标值,则右边指针左移,如果小于目标值,则左边指针右移,整个过程中,需要保证取到满足条件的元祖是唯一不重复的。如果固定过的数有重复的,可以跳过,set记录固定的数。
代码:
public class ThreeSum15 {
public static void main(String[] args) {
int[] num = { -2, 0, 0, 2, 2 };
List<List<Integer>> threeSum = threeSum(num);
System.out.println(threeSum);
}
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ls = new ArrayList<>();
Set<Integer> set = new HashSet<>();
if (nums == null || nums.length == 0)
return ls;
Arrays.sort(nums);
//System.out.println(Arrays.toString(nums));
for (int i = 0; i < nums.length - 2; i++) {
if (set.contains(nums[i]))
continue;
int k = i + 1, j = nums.length - 1;
int target = 0 - nums[i];
while (k < j) {
if (nums[k] + nums[j] > target)
j--;
else if (nums[k] + nums[j] < target)
k++;
else {
List<Integer> list = Arrays.asList(nums[i], nums[k], nums[j]);
if (!ls.contains(list))
ls.add(list);
k++;
j--;
}
}
set.add(nums[i]);
}
return ls;
}
}
输出:[[-2, 0, 2]]