题目描述
分析
1. 暴力
时间负责度过高,不通过
2. 官网
代码实现
public enum Q15 {
instance;
// 官网解法
public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
List<List<Integer>> ans = new ArrayList<List<Integer>>();
// 枚举 a
for (int first = 0; first < n; ++first) {
// 需要和上一次枚举的数不相同
if (first > 0 && nums[first] == nums[first - 1]) {
continue;
}
// c 对应的指针初始指向数组的最右端
int third = n - 1;
int target = -nums[first];
// 枚举 b
for (int second = first + 1; second < n; ++second) {
// 需要和上一次枚举的数不相同
if (second > first + 1 && nums[second] == nums[second - 1]) {
continue;
}
// 需要保证 b 的指针在 c 的指针的左侧
while (second < third && nums[second] + nums[third] > target) {
--third;
}
// 如果指针重合,随着 b 后续的增加
// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if (second == third) {
break;
}
if (nums[second] + nums[third] == target) {
List<Integer> list = new ArrayList<Integer>();
list.add(nums[first]);
list.add(nums[second]);
list.add(nums[third]);
ans.add(list);
}
}
}
return ans;
}
//
public List<List<Integer>> threeSum1(int[] nums) {
List<List<Integer>> lists=new ArrayList<>();
if(nums==null||nums.length<3)return lists;
int l=nums.length;
QuickSort.sort(nums);
for(int i=0;i<l;i++){
if(nums[i]>0){break;}
for(int j=i+1;j<l;j++){
for(int k=j+1;k<l;k++){
// -1 -1 3 4 没必要
if(-(nums[i]+nums[j])<nums[k]){
break;
}
if(!isRepetitive(lists,nums[i],nums[j],nums[k])&&
nums[i]+nums[j]+nums[k]==0){
lists.add(buildList(nums[i],nums[j],nums[k]));
}
}
}
}
return lists;
}
private List<Integer> buildList(int... num){
List<Integer> list=new ArrayList<>();
if(num==null||num.length==0)return list;
for(int i:num){
list.add(i);
}
return list;
}
private boolean isRepetitive(List<List<Integer>> lists,int i,int j,int k){
return lists.stream().anyMatch(list-> {
boolean b = list.stream().allMatch(e -> e == i);
// 0特殊处理
boolean c = ((i != j || i != k || i != 0) || b) &&
(list.contains(i) && list.contains(j) && list.contains(k));
return b||c;
});
}
public static void main(String[] args) {
System.out.println(Q15.instance.threeSum(new int[]{-1, 0, 1, 2, -1, -4}));
System.out.println(Q15.instance.threeSum1(new int[]{-1, 0, 1, 2, -1, -4}));
System.out.println(Q15.instance.threeSum1(new int[]{0,0,0}));
System.out.println(Q15.instance.threeSum1(new int[]{-4,-2,1,-5,-4,-4,4,-2,0,4,0,-2,3,1,-5,0,0}));
System.out.println(Q15.instance.threeSum(new int[]{-4,-2,1,-5,-4,-4,4,-2,0,4,0,-2,3,1,-5,0,0}));
}
}