不会做,参考了代码随想录和力扣官方题解,对此题进行整理。
代码思路
思想:利用双指针法,对数组从小到大排序。先固定一个数,找到其他两个。
(1)首先对数组从小到大排序。
(2)a从左到右遍历数组,每一次遍历的时候设置left指针,right指针。num[a]+num[left]+num[right],如果值等于0,相当于找到了目标元组。如果值大于0,right–;如果值小于0,left++。
(3)涉及到去重的问题。a、left、right都会重复,具体请看下图(↑指a; -指left; =指right)。
a去重:如果在这次循环之前,已经判断了三元组之一的元素num[a](不管是符合条件还是不符合条件,已经判断过这个元素),都跳过。if (num[a] >num[a-1]) continue;
为什么这里不用num[a]和num[a+1]比较,因为会出现元组 -1 -1 2。这是符合条件的。num[a] 和num[a-1]保证的是,在本次循环之前已经判断过这个元素;num[a]和num[a+1]比较还continue的话就是不允许三元组里有重复的元素。
left去重、right去重:找到一个目标元组之后,(且上一步a去重),现在要对left、right去重。如果num[left+1] =num[left], left++;如果num[right-1] =num[right], right–。
(4)技巧:三个数num[a]、num[left]、num[right]相加等于零,因为初始值 left=a+1,right=num.length-1,所以a<left<right这个等式恒成立。又因为num数组从小到大排序,三个数中最小的是a,如果a>0,那么一定不存在这个元组。
20240103重写
20240103第一次重写,错了很多,对着答案改。
语言是 java。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// 不知道怎么初始化List<List<Integer>> ans = new ArrayList<ArrayList<Integer>>();
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);//写错了Arrays.sort(),我写少了一个s
int left,right;
for(int i = 0; i < nums.length; i++) {
if(nums[i] > 0) {
return ans;
}
if(i>0 && nums[i]==nums[i-1]) { //是i>0,不是i>1
continue;
}
left = i+1;
right = nums.length-1;
while(left < right) {
int sum = nums[i] + nums[left] + nums[right];
if(sum > 0) {
right--;
} else if(sum < 0) {
left++;
} else {
ans.add(Arrays.asList(nums[i], nums[left], nums[right]));//不会写
while(right > left && nums[left+1] == nums[left]) {left++;}//为什么要设置right > left
while(right > left && nums[right-1] == nums[right]) {right--;}
//漏写了。
right--;
left++;
}
}
}
return ans;
}
}
错误1
错误2