# 原地址
https://leetcode-cn.com/problems/3sum/
# 分析
- 首先分析数组是乱序的,我们需要对数据进行排序,方便查找相同数据去重复
- 其次因为是3个数字的合,我这边是固定了一个数字,然后计算另外两个数字合为第一个数字的负数,那么3个数字的合也是0。
- 然后第二层循环只需要比较两个指针的合和sum的关系,如果小于sum,需要把start向前移动,如果大于sum,需要把end向后移动,直到start和end碰面就可以结束。
- 当start 和end的合等于sum,我们还要去重复,主要是通过判断当前指针和下一位置的指针是否相等,然后移动。
- 内存循环结束后,又来到外层循环,为了避免重复,外层循环也需要移动重复元素指针。
# 代码
```java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List res = new ArrayList();
if (nums.length < 3) {
return res;
}
// 排序
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
int start = i + 1;
int end = nums.length - 1;
int sum = 0 - nums[i];
while (start < end) {
// 判断
if (nums[start] + nums[end] < sum) {
start++;
} else if (nums[start] + nums[end] > sum) {
end--;
} else {
// 找到了
List list = new ArrayList();
list.add(nums[i]);
list.add(nums[start]);
list.add(nums[end]);
res.add(list);
// 移动重复的start 和 end
while (start < end && nums[start] == nums[start + 1]) {
start++;
}
while (end > start && nums[end] == nums[end - 1]) {
end--;
}
// 移动start前进
start++;
}
}
// 移动第一个指针到不相等的位置
while (i + 1 < nums.length && nums[i] == nums[i + 1]) {
i++;
}
}
return res;
}
}
```
# 提交结果


15. 三数之和