力扣LeetCode第15题三数之和
题目:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
1、首先对数组进行排序
2、既然它需要三个数字加起来等于零,那么我们可以在数组中先选择一个数字,然后再通过左指针和右指针在选择的数字和数组最后一个数字之间移动,让左指针和右指针的值加起来等于选择的数字的相反数即可
3、在左右指针移动的时候,由于是已经排序好的数组,所以如果左右指针的值大于相反数,那么左指针往右移动,反之让右指针往左移动
4、在选择数字的时候可能会有相邻数字相同的情况,那么可以直接跳到下一个数字,不需要再去重复寻找两个数了,因为再次 选择结果是一样的。
5、当左指针和右指针往中间移动的时候,相邻的数字也是一样的那么也是直接继续往一下个移动
代码:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//记录结果
List<List<Integer>> result = new ArrayList<>();
//小于三个数字直接返回
if(nums.length < 3) return result;
//排序
Arrays.sort(nums);
//左指针
int left = 0;
//右指针
int right = nums.length-1;
//目标值(后面会变成for循环循环到的当前值的相反数)
int target = 0;
for (int i = 0; nums[i]<=0&&i<nums.length-2; i++) {
//遍历数组时相同的数字可以直接跳过直接到一下个了,就算去走下面的找另外两个值要么找不到要么是一样的结果
if(i>0 && nums[i] == nums[i-1]) continue;
//目标值变成遍历到当前值的相反数
target = -nums[i];
//每次的左指针是当前遍历到的值的后面一个
left = i + 1;
//每次的右指针则是最右边的值
right = nums.length-1;
while(left <= right-1){
//如果左右指针加起来值小于相反数则左指针往右走
if(nums[left] + nums[right] < target){
left++;
//如果左右指针加起来值大于相反数则右指针往左走
}else if(nums[left] + nums[right] > target){
right--;
}else{
//相等则把值存到结果集中
result.add(Arrays.asList(nums[i],nums[left],nums[right]));
//左指针往右走,右指针往左走,进入下一轮循环,因为可能在中间还有两个值加起来符合条件的
left++;
right--;
//相邻的值相同直接跳到下一个
while(left<right && nums[left]== nums[left-1]) left++;
while(left<right && nums[right]== nums[right + 1]) right--;
}
}
}
return result;
}
}