
方法1:
- 因为不能包含重复三元组,所以先排序,这样更容易去重
- 排序过后遍历第一个数,并保证从第二遍开始与上一次的值不相同,从而起到去重的目的
- 在遍历第一个数的时候,因为已经确定了一个值,所以问题就从刚开始的三元组问题变成了两元组问题,我们只需要将另外两个元素的和等于负的第一个元素的值(我们把它记为a)就可以满足三数之和为0,此时就可以用双指针来解决问题
- 此时让右指针指向最后一个位置
- 所以在遍历第一个数的时候遍历第二个数(也就是让左指针指向第一个数的下一个位置),并且与第2步一样从第二遍开始要保证与上一次的值不同,并且保证左<右()
- 遍历第二个数的时候(也就是左指针右移的过程中),如果两数之和大于a,则让右指针左移直到两数之和重新满足小于a,并且在移动的过程中保证右指针 > 左指针,
- 因为在第6步移动右指针的过程结束后无法确定是因为左右重合跳出循环的,还是因为值小于a跳出循环的,所以要再次判断是否 左==右 ,如果是则break
- 在第二层循环中有满足左值加右值==a,则存入答案中
func threeSum(nums []int) [][]int {
sort.Ints(nums)
ans := [][]int{}
n := len(nums)
for i := 0; i < n; i++ {
if i > 0 && nums[i] == nums[i-1] {
continue
}
r := n-1
a := -nums[i]
for l := i+1; l < r; l++ {
if l > i+1 && nums[l] == nums[l-1] {
continue
}
for r > l && nums[l] + nums[r] > a{
r--
}
if r == l {
break
}
if nums[l] + nums[r] == a {
ans = append(ans,[]int{nums[i],nums[l],nums[r]})
}
}
}
return ans
}