LeetCode(15):三数之和
题目描述:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解题思路:
数组排序 + 双向指针
将数组nums按照从小到达的顺序进行排序。
左指针指向当前元素的下一个元素left = i +1;右指针指向数组末尾元素right = nums.length - 1;
若nums[i]+nums[l]+nums[r] < 0;l++。
若nums[i]+nums[l]+nums[r] >0;r–。
若nums[i]+nums[l]+nums[r]=0,将结果存放到结果集中。l和r继续移动,直到l=r退出。执行下一次循环。
重复结果的避免:
1、若nums[i]+nums[l]+nums[r]=0,l指针向右移动到第一个非重复元素;r指针向左移动到第一个非重复元素。
2、i每次移动到第一个非重复元素。
代码实现:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> target = new ArrayList<>();
//判断特殊情况
if(nums.length < 3){
return target;
}
//对数组进行排序
Arrays.sort(nums);
//利用双指针,l = i + 1,r = nums.length - 1.
//如果三数之和小于0则l++,如果三数之和大于0则r--;
for(int i = 0; i < nums.length;i++){
//数组以排好序,若第i个元素>0,后面元素一定大于0.
if(nums[i] > 0){
break;
}
int l = i + 1;
int r = nums.length - 1;
while((l < r) ){
if( (nums[i] + nums[l] + nums[r]) != 0){
//三数之和大于0,右指针左移
if((nums[i] + nums[l] + nums[r])>0){
r --;
}else{
//三数之和小于0,左指针右移
l++;
}
}else{
//若三数之和==0则将数值存储到结果集中
ArrayList<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[l]);
list.add(nums[r]);
target.add(list);
//左指针右移到第一个不重复的元素
while(l<r && nums[l] == nums[++l]);
//右指针左移到第一个不重复的位置
while(l<r && nums[r] == nums[--r]);
}
}
//将i移动到第一个不重复的元素
while((i+1)<nums.length && nums[i] == nums[i+1]){
i ++;
}
}
//返回结果
return target;
}
}