三数之和
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] nums[j] nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解法
三数之和如何去重是一个比较棘手的问题,在考虑的时候分别考虑对三个数的去重:
对于第一个数,如果遇到相同的直接跳过即可。但是注意应该使用
代码语言:javascript复制if i > 0 && nums[i] == nums[i - 1] {
continue
}
而不是
代码语言:javascript复制if nums[i] == nums[i 1] {
continue
}
使用第二种写法会直接使得[-1, -1, 2]这种情况漏掉
对于第二个第三个数,略过所有重复的第二个和第三个数,考虑[0, 0, 0, 0]这种情况
代码
代码语言:javascript复制func threeSum(nums []int) [][]int {
// 存放答案
result := [][]int{}
// 排序
sort.Ints(nums)
// nums长度
n := len(nums)
for i := 0; i < n-2; i {
a := nums[i]
// 如果第一个数就比0大,就跳出
if a > 0 {
break
}
if i > 0 && nums[i] == nums[i-1] {
continue
}
// 找第二个数的指针
leftP := i 1
// 找第三个数的指针
rightP := n - 1
for leftP < rightP {
if a nums[leftP] nums[rightP] == 0 {
//找到了一个三元组
result = append(result, []int{a, nums[leftP], nums[rightP]})
//为后两个数去重,防止找到重复的
leftP
for leftP < rightP && nums[leftP] == nums[leftP-1] {
leftP
}
rightP--
for leftP < rightP && nums[rightP] == nums[rightP 1] {
rightP--
}
} else if a nums[leftP] nums[rightP] > 0 {
rightP--
} else {
leftP
}
}
}
return result
}
性能:
代码语言:javascript复制执行用时:40 ms, 在所有 Go 提交中击败了94.49%的用户
内存消耗:7.4 MB, 在所有 Go 提交中击败了70.64%的用户
通过测试用例:312 / 312