给定一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
思路:
首先对数组排序,使用快排。然后用一个for来遍历数组,首先判断该数是否大于0,如果大于0,那么就直接break掉,因为后面的数加起来不可能等于0;如果小于0,首先计算target = 0 - nums[i]的值,然后在[i+1,nums.length - 1]中扫描,找到和为target的数字。
方法:
使用类似快排的方法来进行扫描:
- 设置前后两个指针k和j
- 如果nums[i]+nums[j] == target,把nums[i],nums[k],nums[j]依次放入list中,然后k++,j--。
- 如果nums[i]+nums[j] > target,j--
- 如果nums[i]+nums[j] < target,k--
代码:
public static List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Set<List<Integer>> set = new HashSet<>();
if (nums.length < 3){
return result;
}
sort(nums,0,nums.length - 1);
int target,k,j;
for (int i = 0; i < nums.length -2; i++){
if (nums[i] >0){
break;
}else {
target = 0 - nums[i];
k = i + 1;
j = nums.length - 1;
while (k < j){
int s = nums[k] + nums[j];
if (s == target){
List<Integer> temp = new ArrayList<>();
temp.add(nums[i]);
temp.add(nums[k]);
temp.add(nums[j]);
set.add(temp);
k++;
j--;
}else if (s > target){
j --;
}else {
k ++;
}
}
}
}
result.addAll(set);
return result;
}
/**
* 快速排序
*/
public static void sort(int[] a,int low,int high ){
int start = low;
int end = high;
int key = a[low];
if (high > low ) {
while (start != end) {
while (end > start && a[end] >= key) {
end --;
}
if (start < end) {
a[start] = a[end];
start ++;
}
while (end > start && a[start] <= key) {
start ++;
}
if (start < end) {
a[end] = a[start];
end --;
}
}
a[start] = key;
if (start - 1 >= 0) {
sort(a, low, start - 1);
}
if (start + 1 < high) {
sort(a, start + 1, high);
}
}
}