题目
给你一个包含 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 = []
输出:[]示例 3:
输入:nums = [0]
输出:[]提示:
0 <= nums.length <= 3000
-10^5 <= nums[i] <= 10^5来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
暴力立方级复杂度肯定过不了,因此需要考虑最多平方(10^6级)的算法。
先将数组排序,枚举第一个数,使用双指针找后面两个数,根据三数之和和0的大小关系决定两个指针的移动。
注意可能会有重复的数,因此需要去重。
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
int n = nums.length;
for (int i = 0; i < n - 2; i++) {
// 针对第一个数的去重
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int first = nums[i];
int p = i + 1;
int q = n - 1;
while (p < q) {
int sum = nums[p] + nums[q] + first;
if (sum == 0) {
ans.add(List.of(first, nums[p], nums[q]));
// 针对第二三个数进行去重,跳过相等的数
while (p + 1 < n && nums[p] == nums[p + 1]) {
p++;
}
while (q - 1 >= 0 && nums[q] == nums[q - 1]) {
q--;
}
// 注意要先跳过相等的数后,再移动一位,这两步不能交换顺序,即不能放在while之前
p++;
q--;
} else if (sum > 0) {
q--;
} else {
p++;
}
}
}
return ans;
}
}