用到的算法知识: 排序+双指针
遍历时当前下标,定住 作为符合条件第一个元素,然后双指针为l=i+1,r=n-1,代表剩余的两个元素。
算法思路
-
排序
-
特判,对于数组长度小于3的,返回[].
-
遍历数组
- 若nums[i]>0: 因为已经排序好,所以后面的数都是正数,不可能存在符合条件的情况了
- 循环双指针,条件l<r
- 当sum>0 r--
- 当sum<0 l++
- 当sum==0 添加到答案中,并检查l,r的下一位是否与当前值相同,相同就跳过
- 最后nums[i]也要跳过重复的元素
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList();
//先将数组排好序,然后遍历i,双指针为l= i+1,r = n-1
if(nums.length < 3)
return ans;
Arrays.sort(nums);
for(int i = 0; i < nums.length-2; i++) {
if(nums[i] > 0)
break;
//在有序的区间中进行双指针遍历
int l = i+1,r = nums.length-1;
while(l<r){
int sum = nums[i] + nums[l] + nums[r];
if(sum>0) {
r--;
}
else if(sum<0){
l++;
}
else {
List<Integer> list = new ArrayList();
list.add(nums[i]);
list.add(nums[l]);
list.add(nums[r]);
ans.add(list);
//得到一种答案时,要跳过l,r中下一个重复的数,保证去重
while(l+1<nums.length&&l<r&&nums[l]==nums[l+1]){
l++;
}
while(r-1>=0&&l<r&&nums[r]==nums[r-1]){
r--;
}
l++;
r--;
}
}
//i也一样,跳过重复的数
while(nums[i]==nums[i+1]&&i<nums.length-2)
i++;
}
return ans;
}
}