1 描述
2 思路
1 首先将数组进行排序–调用Arrays.sort(nums)即可
2 然后定义三个指针:
第一个指向数组第一个,
第二个为left指针,它一开始作为第一个指针右边的一个,
第三个指针为right为数组最后一个元素的位置
3 这里思路就是,第一个指针 加 left 加 right
3.1 大于0的时候,说明加的多了,因此让右边往左移动
3.2小于0的时候,说明加的少了,因此让左边往右移动
3.3 等于0的时候,说明找到了结果,这样就加入结果集
4 这里需要进行去重操作,分为3个去重,
4.1 在for循环第一个指针的时候,若第一个指针它的下一个值和自己相等,那么说明当前的结果集会包含下个指向元素的结果集 因此需要第一个指针继续向下移动,直到找到与自己不一样的
4.2 在第一个指针加left加right等于0的时候,此时left要向右移动,right要向左移动,注意在移动的时候
若left和right发现下一个和自己相等,那么当前自己的结果集就包含下一个的结果集,因此需要继续向下寻找与自己不相等的值。
5 此题重点需要理解第三步,然后在理解第4步去重,此题在代码随想录的三数之和有着更加充分的解释
3 代码
public class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//先进行排序
Arrays.sort(nums);
//创建结果数组
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
//先做初始判断,第一个数就是大于0的数,那么排过序的加起来肯定不为0
if (nums[i] > 0) {
return result;
}
//若当前三数的第一个数与上一个相等,那么此次的i就不用继续判断了,因为上一个的结果结果是含有此次的结果
if ((i > 0) && (nums[i] == nums[i - 1])) {
continue;
}
int left = i + 1;
int right = nums.length - 1;
//当left和right指向同一个元素的的时候就不进行判断了
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum > 0) { //若当前三数之和大于0,说明应该加一个小的数,因此向左移动
right--;
} else if (sum < 0) { //若当前三数之和小于0,说明应该加一个大的数,因此向右移动
left++;
} else {//若当前三数之和等于0,则加入结果数组
//加入结果数组--
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
//进行去重判断--若右边往左移动的时候发现它的下一个和自己相等,那么当前指向结果集就包含了下个指向的结果集
//因此继续找和自己不一样的,来完成去重
while (right > left && nums[right] == nums[right - 1]) right--;
//进行去重判断--若左边往右移动的时候发现它的下一个和自己相等,那么当前指向结果集就包含了下个指向的结果集
//因此继续找和自己不一样的,来完成去重
while (right > left && nums[left] == nums[left + 1]) left++;
//当前left和right准备移动的下一个都与自己不相等,此时两个指针都往下一个移动
right--;
left++;
}
}
}
return result;
}
}