特此说明:这些解题代码都是我解题时根据自己的解题思路或他人的解题思路自己敲得,新人,难免会有代码冗余,只能保证思路和代码结果正确,解题的方法因本人能力有限,只能给出我知道,我会的,另外大佬轻点喷。
题目(力扣原题):
解题:
- 找关键词:整数数组nums,满足 nums[i] + nums[j] + nums[k] == 0,且i != j、i != k 且 j != k,返回所有和为 0 且不重复的三元组。
- 题意分析: 就是求返回所有和为 0 且不重复的三元组。
- 根据示例找细节:不要求返回数组中值的顺序,数组可以为空,在一个数组内值可以重复但下标一定要不同。
解法一:暴力破解
思路:将三元数组转换为二元数组,求出所有下标不同和为0的数组,最后去重。
public List<List<Integer>> threeSum(int[] nums) {
//思路,将三元转为二元
List<List<Integer>> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
list2.add(0,1);
list2.add(1,1);
list2.add(2,1);
int a[]=new int[3*nums.length*(nums.length-1)/2];
int d=-1,c=0,e=0,f=0;
//将想x+y=m放入一个新数组,i j m d用来确定下标
for (int i = 0; i < nums.length-1; i++) {
for (int j= i+1; j < nums.length; j++) {d++;
a[3*d]=i;
a[3*d+1]=j;
a[3*d+2]=nums[i]+nums[j];
}
}
//跳3位,获取和就行,减1减2就是下标
for (int i = 2; i < a.length; i+=3) {
for (int j = 0; j < nums.length; j++) {
//判断下标是否相等
if ((a[i-1])!=j&&(a[i-2])!=j){
if ((a[i]+nums[j])==0){
//每次创建一个新的空间,防止数据的堆叠
List<Integer> list0 = Arrays.asList(1,1,1);
list0.set(0,nums[a[i-1]]);
list0.set(1,nums[a[i-2]]);
list0.set(2,nums[j]);
Collections.sort(list0);
list1.add(list0);
}
}
}
}
for (int i = 0; i < list1.size(); i++) {
for (int j = i+1; j < list1.size(); j++) {
if (list1.get(i).get(0)==list1.get(j).get(0)&&list1.get(i).get(1)==list1.get(j).get(1)&&list1.get(i).get(2)==list1.get(j).get(2)){
list1.remove(j);
j--;
}
}
}
return list1;
}
}
解法二:双指针法
思路:按升序对数组排序,将三数之和问题转为两数之和,确定第一个值nums[i],再将其余两个值的指针分别为b=i+1,c=nums.length-1,一头一尾。以为数组为升序,如果和大于0则c–,如果小于0则b++。
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> lists = new ArrayList<>();
//对数组排序
Arrays.sort(nums);
//利用双指针 左,右 a+b+c 固定a
for (int i = 0; i < nums.length; i++) {
//a元素去重,与之前那个比
if (i>0&&nums[i]==nums[i-1]){
//想同就跳过本次循环,i++,换个a
continue;
}
//当a大于0时不存在
if (nums[i]>0){
return lists;
}
int b=i+1;
int c=nums.length-1;
while (b<c){
//当和大于0时,c减小
if (nums[i]+nums[b]+nums[c]>0){
c--;
}else
//当和小于0时,b增大
if (nums[i]+nums[b]+nums[c]<0){
b++;
}else {
//每次都要创建一个新的,不然数据会重叠
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[b]);
list.add(nums[c]);
lists.add(list);
//b加一后的数相等就再加一
while (b<c&&nums[b]==nums[b+1]){
b++;
}
//c减一后的数相等就再减一
while (b<c&&nums[c]==nums[c-1]){
c--;
}
b++;
c--;
}
}
}
return lists;
}