给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
有两种写法:第一种耗时久,但容易解读
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> list=new ArrayList<>();
Arrays.sort(nums);
if(nums.length==0 || nums[0]>0){
return list;
}
if(nums.length>=3){
for(int i=0;i<nums.length-2;i++){
int k=i+1;
int z=nums.length-1;
while(k<z) {
List<Integer> list1=new ArrayList<>();
if (nums[i] + nums[k] + nums[z] > 0) {
z--;
}else if(nums[i] + nums[k] + nums[z] <0){
k++;
}else{
list1.add(nums[i]);
list1.add(nums[k]);
list1.add(nums[z]);
if(!list1.isEmpty()){
list.add(list1);
}
while (k < z && nums[k] == nums[k + 1]) k++;
while (k < z && nums[z] == nums[z - 1]) z--;
k++;
z--;
}
}
}
}
LinkedHashSet<List<Integer>> set = new LinkedHashSet<>(list.size());
set.addAll(list);
list.clear();
list.addAll(set);
return list;
}
}
第二种耗时少,但看不太懂,还是贴出来供大家参考
public static List<List<Integer>> threeSum(int[] nums) {
if (nums.length < 3)
return Collections.emptyList();
List<List<Integer>> res = new ArrayList<>();
int minValue = Integer.MAX_VALUE;
int maxValue = Integer.MIN_VALUE;
int negSize = 0;
int posSize = 0;
int zeroSize = 0;
for (int v : nums) {
if (v < minValue)
minValue = v;
if (v > maxValue)
maxValue = v;
if (v > 0)
posSize++;
else if (v < 0)
negSize++;
else
zeroSize++;
}
if (zeroSize >= 3)
res.add(Arrays.asList(0, 0, 0));
if (negSize == 0 || posSize == 0)
return res;
if (minValue * 2 + maxValue > 0)
maxValue = -minValue * 2;
else if (maxValue * 2 + minValue < 0)
minValue = -maxValue * 2;
int[] map = new int[maxValue - minValue + 1];
int[] negs = new int[negSize];
int[] poses = new int[posSize];
negSize = 0;
posSize = 0;
for (int v : nums) {
if (v >= minValue && v <= maxValue) {
if (map[v - minValue]++ == 0) {
if (v > 0)
poses[posSize++] = v;
else if (v < 0)
negs[negSize++] = v;
}
}
}
Arrays.sort(poses, 0, posSize);
Arrays.sort(negs, 0, negSize);
int basej = 0;
for (int i = negSize - 1; i >= 0; i--) {
int nv = negs[i];
int minp = (-nv) >>> 1;
while (basej < posSize && poses[basej] < minp)
basej++;
for (int j = basej; j < posSize; j++) {
int pv = poses[j];
int cv = 0 - nv - pv;
if (cv >= nv && cv <= pv) {
if (cv == nv) {
if (map[nv - minValue] > 1)
res.add(Arrays.asList(nv, nv, pv));
} else if (cv == pv) {
if (map[pv - minValue] > 1)
res.add(Arrays.asList(nv, pv, pv));
} else {
if (map[cv - minValue] > 0)
res.add(Arrays.asList(nv, cv, pv));
}
} else if (cv < nv)
break;
}
}
return res;
}