package part01;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
* 排序
* 去重
* 然后计算需要的值
*/
public class threeSum {
public static List threeSumFunction(int[] nums) {
/*
* 第一次失败
**/
// List result = new ArrayList();
// if (nums.length > 2) {
// HashMap<Integer, Integer> numsMap = new HashMap<>();
// for (int i = 0; i < nums.length; i++) {
// numsMap.put(nums[i],i);
// }
// for(int i = 0; i < nums.length; i++){
// if(i==numsMap.get(nums[i])){
//
// }
//
// }
//
// } else {
// throw new IllegalArgumentException("the length of nums is less than 3");
// }
/*
* 第二次失败,失败的原因为存在重复值需要考虑去重,去重可以考虑对目标值进行排序
* */
// if (nums.length > 2) {
// HashMap<Integer, Integer> numsMap = new HashMap<>();
// for (int i = 0; i < nums.length; i++) {
// numsMap.put(nums[i],i);
// }
// List result = new ArrayList();
// for (int i = 0; i < nums.length - 2; i++) {
// for (int j = i + 1; j < nums.length - 1; j++) {
// for (int k = j + 1; k < nums.length; k++) {
// if (nums[i] + nums[j] + nums[k] == 0) {
// //这里的对象不能在上面创建,如果是在最上面创建的就会导致最终返回值里的每个arr都是一样的。必须做到每次都是这一个唯一确定才行。
// result.add(new int[]{nums[i], nums[j], nums[k]});
//
// }
//
// }
// }
// }
// return result;
// } else {
// throw new IllegalArgumentException("the length of nums is less than 3");
// }
// }
/*第三次
*
*本次将 -1 -1 0的值过滤掉了,原因为做了前一个值和后一个值不相同的限定
* 添加上if(i > 0 && nums[i] == nums[i-1]) continue; 后可以输出为正确的答案,但是存在为[0,0,0,0]时的问题
* **/
// List result = new ArrayList();
// if (nums == null) {
// return null;
// }
// int len = nums.length;
// if (len < 3) return result;
// Arrays.sort(nums);
// for (int i = 0; i < len - 2; i++) {
// if(i > 0 && nums[i] == nums[i-1]) continue;
// for (int j = i + 1; j < len - 1; j++) {
// for (int k = j + 1; k < len; k++) {
// if (nums[i] + nums[j] + nums[k] == 0) result.add(new int[]{nums[i], nums[j], nums[k]});
// }
// }
// }
// return result;
// }
//}
//
// /*
// * 第四次
// * 参考leetcode的解析答案
// *
// *
// * */
// List result = new ArrayList();
// if (nums == null) return null;
// int len = nums.length;
// if (len < 2) return result;
// Arrays.sort(nums);
// for (int i = 0; i < len - 1; i++) {
如果最小的数已经大于0了就不需要再循环了
// if(nums[i] > 0) break;
开始的处理方法为:
// if (i <len-1 && (nums[i] == nums[i + 1])) continue;
去重
if (i >0 && (nums[i] == nums[i - 1])) continue;
// int L = i + 1;
// int R = len - 1;
//
// while (L < R) {
保障每次 L和R变化之后 都会重新产生新的sum
// int sum = nums[i] + nums[L] + nums[R];
// if (sum == 0) {
// result.add(new int[]{nums[i], nums[L], nums[R]});
两种方法
result.add(Arrays.asList(nums[i],nums[L],nums[R]));
// if (L < R && nums[L] == nums[L + 1]) L++; // 去重
// if (L < R && nums[R] == nums[R - 1]) R--; // 去重
// L++;
// R--;
// } else if (sum > 0) R--;
// else L++;
// }
// }
// return result;
//
// }
/*
* 第五次
* 参考leetcode的解析答案
* 第四次在重复值问题上是算了重复值的后一个值,这样导致L的值不能取到与i对应数组中的数据,会导致取不到-1,-1,0
*
*
* */
List result = new ArrayList();
if (nums == null) return null;
int len = nums.length;
if (len < 2) return result;
Arrays.sort(nums);
for (int i = 0; i < len; i++) {
// 如果最小的数已经大于0了就不需要再循环了
if (nums[i] > 0) break;
// 开始的处理方法为:
if (i > 0 && (nums[i] == nums[i - 1])) continue;
// 去重
// if (i >0 && (nums[i] == nums[i - 1])) continue;
int L = i + 1;
int R = len - 1;
while (L < R) {
// 保障每次 L和R变化之后 都会重新产生新的sum
int sum = nums[i] + nums[L] + nums[R];
if (sum == 0) {
// result.add(new int[]{nums[i], nums[L], nums[R]});
// 两种方法
result.add(Arrays.asList(nums[i], nums[L], nums[R]));
// 此处不能用if判断,用了if就会导致如果连续三次重复的话,还是会有重复的数据存在。这里需要用while
while (L < R && nums[L] == nums[L + 1]) L++; // 去重
while (L < R && nums[R] == nums[R - 1]) R--; // 去重
L++;
R--;
} else if (sum > 0) R--;
else L++;
}
}
return result;
}
}