题干:
思路:
首先想到的是哈希表,类似于两数之和的想法,共两层循环,将遍历到的第一个元素和第二个元素存入哈希表中,然后按条件找第三个元素,但是这道题有去重的要求,哈希表实现较为麻烦。
优解是用双指针的解法,将数组排序,排序的目的是为了后续定义的判定条件,题干要求返回的是数组中的值,并不是索引所以可以排序。排完序,先固定第一个元素,然后固定左指针和右指针
当三个元素和大于0时,需要将右指针左移,元素和小于0时,将左指针右移。另外还要考虑去重。
代码实现如下:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
//对数组进行排序
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
//如果第一个数字已经大于0,则凑不成三元组
if(nums[i] > 0){
return res;
}
//对第一个数字去重
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
//记录第一个数字
int temp = nums[i];
//定义双指针
int left = i + 1;
int right = nums.length - 1;
while(right > left){
int sum = temp + nums[left] + nums[right];
if(sum > 0){
right--;
}else if(sum < 0){
left++;
}else {
//Arrays.asList():将数组转换为一个固定的列表
res.add(Arrays.asList(temp, nums[left], nums[right]));
//对第二个和第三个数数字去重
while(right > left && nums[right] == nums[right-1]){
right--;
}
while(left < right && nums[left] == nums[left + 1]){
left++;
}
right--;
left++;
}
}
}
return res;
}
}