67,636
社区成员
发帖
与我相关
我的任务
分享1、题目
LeetCode 15. 三数之和 难度级别 Mid
题目: 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组
2、解答
思路: 三元组使用哈希去操作非常复杂,去重过程难以处理,故采用先固定第一个元素,然后剩下两个元素使用两个指针来遍历的方法。另外两个元素做相似的去重处理。
关键词: 双指针,同一个数组中的三数之和
知识点: 将数组的一部分元素合为list,并返回这个list,Arrays.asList(nums[i], nums[left], nums[right]));数组排序,Arrays.sort(nums);
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//注意一个条件,不包含重复的三元组,这个条件无法或者说很难通过哈希来解决(需要三重去重)
//思想:如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) {//如果第一个元素大于0,因为递增的性质,无论如何都无法=0了
return result;
}
if (i > 0 && nums[i] == nums[i - 1]) {//兼顾考虑[-1,-1,2]的情况
continue;
}
int left = i + 1;//left,right前闭后闭区间
int right = nums.length - 1;
while (right > left) {//常规 循环条件
int sum = nums[i] + nums[left] + nums[right];
if (sum > 0) {//大于0则缩小right
right--;
} else if (sum < 0) {//小于0则增大left
left++;
} else {//满足条件
result.add(Arrays.asList(nums[i], nums[left], nums[right]));//将数组的一部分元素合为list
while (right > left && nums[right] == nums[right - 1]) right--;//去重尾部分
while (right > left && nums[left] == nums[left + 1]) left++;//去重头部分
//找到一个符合条件的list之后,收缩指针
right--;
left++;
}
}
}
return result;
}
}