LeetCode传送门:三数之和
题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意 :答案中不可以包含重复的三元组。
实例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路
排序+双指针
本体难点在于如何去除重复。
算法流程
- 特判,对于数组长度 n,如果数组为 null或者数组长度小于 3,返回[]。
- 对数组进行排序。
- 遍历排序后数组:
- 若 nums[i]>0:在已排好顺序的数组中不可能有三个数加和等于 0,直接返回结果。
- 对于重复元素:跳过,避免出现重复解,如
if (i>0 && nums[i-1]==nums[i]) continue;
- 令左指针
j=i+1
,右指针k=nums.length-1
,当j<k
时,执行循环:- 当
nums[i]+nums[j]+nums[k]==0
时,j++,k--
并同时 执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将j,k
移到下一位置,寻找新的解 - 若和大于 0 ,说明
nums[k]
太大,k
左移
若和小于 0 ,说明nums[j]
太小,j
右移
- 当
Java代码实现
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> resulet = new ArrayList<>();
if (nums.length<3 || nums==null) return resulet;
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i]>0) return resulet;
if (i>0 && nums[i-1]==nums[i]) continue;
int j = i+1;
int k = nums.length-1;
while (j<k){
if (nums[i]+nums[j]+nums[k]==0){
ArrayList<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
resulet.add(list);
j++;
k--;
while (j<nums.length && nums[j]==nums[j-1]) j++;
while (j<k && nums[k]==nums[k+1]) k--;
}else if (nums[j]+nums[k]>-nums[i])
k--;
else
j++;
}
}
return resulet;
}
}
如有错误之处请留言指正。