目录
题目一:三数之和
题目详述:给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
重难点:这道题的重难点主要是在处理去重的细节上面。
思路:将数组排好序之后,对每一个值都进行一次固定,固定好当前值之后,在当前值的后面圈定个范围,去寻找另外两个符合要求(数不同且和为0,道不同却相为谋嘛)的数。在处理的过程中要注意对于去重的细节处理。代码的每一行都标有较为详细的解释。
tips : 去重为了解决哪种测试用例?
如:(排完序之后)
-4,-1,-1,-1,2,2,2,2
如果不去重
当i在第二个 -1 位置上时,集合中已经有结果为: (-1,-1,2)
此时的 i , left , right 分别走到了:
-4,-1,-1,-1,2,2,2,2
i left right
如果不去重 在集合中又会添加一个结果为:(-1,-1,0)
代码实现:
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
//将数组进行排序之后
//依次将每一个数进行单独的固定
//再用两个指针来圈定一个范围 ,在这个范围中找到两个数去和被固定的数进行匹配
//在处理的过程中要注意去重的细节
if(nums.length < 3){
return result;
}
//将数组进行排序
Arrays.sort(nums);
//依次锁定每一个数
for(int i = 0;i < nums.length;i++){
//如果当前i位置的数是大于0的 并且数组是有序则后面的数肯定都大于0 直接退出
if(nums[i] > 0){
break;
}
//去重
//如果i和其前一个位置相等 则极有可能会出现重复的结果
//所以如果出现这种情况需要将当前的i跳过
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
//此时已经固定了一个i的位置 需要圈定一个位置
//在这个范围内 选择所有符合条件的另外两个数
int left = i + 1;
int right = nums.length - 1;
//题目规定不能用重复的一个数 所以left不能等于right
while(left < right){
//得到当前三个数的结果
int curSum = nums[left] + nums[right] + nums[i];
if(curSum == 0){
//将结果添加到集合中
result.add(Arrays.asList