个人理解:
1.使用双指针做法,首先对数组进行排序
第一重for循环控制第一个数,对数组进行遍历。双指针初始化为left=i+1, rigth=nums.length-1。然后使用while循环移动双指针寻找合适的数。因为返回的是数,不是下标,数不能重复,所以需要去重。对于第一重for循环,当i大于0的时候,要判断是否和前一个数相同,如果相同,则跳过当前数进行去重。
2.双指针移动
当nums[i]+nums[left]+nums[right]>0时,说明大了,最右边的right指针需要减减操作(right--)
当nums[i]+nums[left]+nums[right]<0时,说明小了,最左边的left指针需要加加操作(left++)
当nums[i]+nums[left]+nums[right]==0时,开始收集结果。
3.结果收集
收集完结果后,要移动双指针,这时候也要对双指针进行去重。
指针去重操作:
对于left指针,如果nums[left]==nums[left+1],说明下一位重复,那么left要持续++;
对于right指针,如果nums[right]==nums[right-1],说明下一位重复,那么right要持续--;
以上两种情况都要主要前提条件,即left<right
无论以上两种情况是否执行,都需要left++和right--更新双指针。
最后将结果收集 res.add(Arrays.asList(nums[i],nums[left],nums[right]))
res是List<List<Integer>>类型,Arrays.asList()是将一组元素变为List
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++){
if(nums[i]>0) //如果第一个元素大于0,直接跳出循环
break ;
if(i>0&&nums[i]==nums[i-1]) //对于第一个元素,去重
continue;
int left=i+1; // 双指针
int right=nums.length-1;
// 指针开始移动
while(left<right){
if(nums[i]+nums[left]+nums[right]>0){ // 太大了,右指针移动
right--;
}
else if(nums[i]+nums[left]+nums[right]<0){ // 太小了,左指针移动
left++;
}
else{
//收集结果
res.add(Arrays.asList(nums[i],nums[left],nums[right]));
// 开始对指针去重,也就是对第二、第三个元素去重
while(left<right&&nums[right]==nums[right-1])
right--;
while(left<right&&nums[left]==nums[left+1])
left++;
// 移动双指针
left++;
right--;
}
}
}
return res;
}
}