题目描述
题目描述:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
输入: {-1, 0, 0, 4, 1, 2, -1, -3, -2, -4};
输出:
[
[-4, 0, 4],
[-3, -1, 4],
[-3, 1, 2],
[-2, 0, 2],
[-1, -1, 2],
[-1, 0, 1]
]
解题思路
- 每个数只使用一次,如果三个for循环会产生大量重复数据,而且也容易一个数使用多遍,所以不可
- 所以可以最外层定义一个循环,该循环遍历到的值作为内存循环的定值 i
- 内层定义两个指针,left、right。指针初始位置为剩余数值的两端
- 两个指针left、right向中间移动,并判断是否符合题目条件
图例:
第一次循环:
第二次循环的起始位置,其余于第一次循环一致:
代码示例
public class Test {
public static void main(String[] args) {
int[] nums = {-1, 0, 0, 4, 1, 2, -1, -3, -2, -4};
List<List<Integer>> lists = threeSumEqualZero(nums);
System.out.println("符合条件的集合为:"+lists.toString());
}
public static List<List<Integer>> threeSumEqualZero(int[] nums) {
List<List<Integer>> ans = new ArrayList();
int len = nums.length;
if(nums == null || len < 3) {
return ans;
}
//对数组进行排序
Arrays.sort(nums);
//i为一次循环的定值,left、right为一次循环的变值
for (int i = 0; i < len ; i++) {
// 如果当前数字大于0,则三数之和一定大于0,所以结束循环
if(nums[i] > 0) {
break;
}
// 去重
if(i > 0 && nums[i] == nums[i-1]) {
continue;
}
//初始化变动的两个值left、right
int left = i+1;
int right = len-1;
while(left < right){
int sum = nums[i] + nums[left] + nums[right];
if(sum == 0){
//添加到返回集合中
ans.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left+1]) {
left++; // 去重
}
while (left < right && nums[right] == nums[right-1]) {
right--; // 去重
}
left++;
right--;
}else if (sum < 0) {
left++;
}else if (sum > 0) {
right--;
}
}
}
return ans;
}
}
运行结果
来源:CSDN
作者:程序人生_高少猛
链接:https://blog.csdn.net/weixin_43954926/article/details/104184717