题目:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解法一:
用排序+哈希表法,但是需要注意剪枝:
func threeSum(nums []int) [][]int {
var result [][]int
sort.Ints(nums)
m := make(map[int]int)
for i := 0; i < len(nums); i++ {
m[nums[i]] = i
}
for i := 0; i < len(nums) ; i++ {
if i > 0 && nums[i] == nums[i-1] {
continue
}
for j := i+1; j < len(nums); j++ {
if j > i+1 && nums[j] == nums[j-1] {
continue
}
z := 0 - nums[i] - nums[j]
if index, ok := m[z]; ok {
if index > j {
newArray := []int{nums[i], nums[j], z}
result = append(result, newArray)
} else {
//只有比nums[j] 更小索引的值才能满足要求,则nums[j+1]更不行,于是break,查找下一个i
break
}
}
}
}
return result
}
解法二:
排序+双指针法:
func threeSum(nums []int) [][]int {
var result [][]int
sort.Ints(nums)
for i := 0; i < len(nums)-2 ; i++ {
//同样,利用排序后的有序性,跳过重复元素
if i > 0 && nums[i] == nums[i-1] {
continue
}
//双指针
j := i + 1
k := len(nums) - 1
target := 0 - nums[i]
for ;j < k; {
if nums[j] + nums[k] == target {
resultArray := []int{nums[i], nums[j], nums[k]}
result = append(result, resultArray)
//注意这里是跳过重复元素
for ; j < k && nums[j]==nums[j+1]; {j++}
for ; j < k && nums[k-1]== nums[k]; {k--}
j++
k--
} else if nums[j] + nums[k] > target {
k--
} else {
j++
}
}
}
return result
}