leetCode练习总目录
一、三数之和
/**
* 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
*
*/
public List<List<Integer>> threeSum(int[] nums) {
ArrayList result = new ArrayList();
ArrayList<Integer> numList = new ArrayList<>();
for (int num : nums) {
numList.add(num);
}
List<Integer> sortNum = numList.stream().sorted(
(o1, o2) -> o1 - o2
).collect(Collectors.toList());
int numSize = sortNum.size();
Set<Integer> distinct1 = new HashSet<>();
Set<Integer> distinct2 = new HashSet<>();
for (int i = 0; i < numSize; i++) {
//遍历数组
//左边最小数字
int minNum = sortNum.get(i);
//如果已经处理过相同的直接过滤
if (distinct1.add(minNum)) {
//最大值偏移量
int maxIndex = 0;
for (int j = numSize - 1 - maxIndex; j > i; j--) {
//反向遍历最大值
int maxNum = sortNum.get(j);
//最大值和最小值之差
int step = minNum + maxNum;
//存在相同的直接不处理
if (distinct2.add(maxNum)) {
if (step > 0 && step <= Math.abs(minNum)) {
//说明需要加小于0的值,从i下一位开始并且需要小于j
for (int i1 = i + 1; i1 < j; i1++) {
//中间值
int mid = sortNum.get(i1);
if (step + mid == 0) {
int[] ints = {mid, minNum, maxNum};
result.add(ints);
//这里需判断i和maxIndex是否需要移动
maxIndex++;
break;
} else if (step + mid > 0) {
break;
}
}
} else if (step <= 0 && Math.abs(step) <= maxNum) {
//说明需要加大于0的值,从i下一位开始并且需要大于j
for (int i1 = j - 1; i1 > i; i1--) {
//中间值
int mid = sortNum.get(i1);
if (step + mid == 0) {
int[] ints = {mid, minNum, maxNum};
result.add(ints);
//这里需判断i和maxIndex是否需要移动
maxIndex++;
break;
} else if (step + mid < 0) {
break;
}
}
}
}
}
distinct2.clear();
}
}
return result;
}