package main
import (
// "fmt"
"fmt"
"sort"
)
func main() {
nums := []int{-1, -1, 2, 0, -2, -2, 4}
fmt.Println(threeSum(nums))
}
func threeSum(nums []int) [][]int {
// 先从小到大排序
sort.Ints(nums)
// 接收结果
var res [][]int
// 获取数组长度
length := len(nums)
// 边界处理,数字不足三个直接返回空
if len(nums) < 3 {
return res
}
// 开始循环第一个固定值
for index, _ := range nums {
// 如果固定位的值已经大于0,因为已经排好序了,后面的两个指针对应的值也肯定大于0,则和不可能为0,所以返回
if nums[index] > 0 {
return res
}
// 排除值重复的固定位
if index > 0 && nums[index] == nums[index-1] {
continue
}
// 指针初始位置,固定位右边第一个和数组最后一个
l := index + 1
r := length - 1
// 开始移动两个指针
for l < r {
// 判断三个数字之和的三种情况
sum := nums[index] + nums[l] + nums[r]
switch {
case sum == 0:
// 将结果加入二元组
res = append(res, []int{nums[index], nums[l], nums[r]})
// 去重,如果l < r且下一个数字一样,则继续挪动
for l < r && nums[l] == nums[l+1] {
l++
}
// 同理
for l < r && nums[r] == nums[r-1] {
r--
}
l++
r--
case sum > 0:
// 如果和大于 0,那就说明 right 的值太大,需要左移
r--
// 如果和小于 0,那就说明 left 的值太小,需要右移
case sum < 0:
l++
}
}
}
return res
}