50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
|
func threeSum(nums []int) (result [][]int) {
|
||
|
target := 0
|
||
|
sort.Ints(nums)
|
||
|
|
||
|
for i := 0; i < len(nums)-2; i++ {
|
||
|
// We don't want duplicates of the fixed value
|
||
|
// which can cause duplicate triplets to appear.
|
||
|
if i > 0 && nums[i] == nums[i-1] {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
startPtr := i + 1
|
||
|
endPtr := len(nums) - 1
|
||
|
|
||
|
for startPtr < endPtr {
|
||
|
sum := nums[i] + nums[startPtr] + nums[endPtr]
|
||
|
|
||
|
if sum == target {
|
||
|
result = append(
|
||
|
result,
|
||
|
[]int{nums[i], nums[startPtr], nums[endPtr]},
|
||
|
)
|
||
|
|
||
|
// Duplicate values can appear while scanning also. Presence of these
|
||
|
// duplicate values can also result in duplicate triplets. So, for the
|
||
|
// start and end pointers, we need to keep moving them until we are
|
||
|
// clear of duplicates.
|
||
|
for startPtr < endPtr && nums[startPtr] == nums[startPtr+1] {
|
||
|
startPtr++
|
||
|
}
|
||
|
|
||
|
for endPtr > startPtr && nums[endPtr] == nums[endPtr-1] {
|
||
|
endPtr--
|
||
|
}
|
||
|
|
||
|
// Since the loops above stop at the last duplicate value, we need to move
|
||
|
// them by one step from both directions to continue with the logic.
|
||
|
startPtr++
|
||
|
endPtr--
|
||
|
} else if sum < target {
|
||
|
startPtr++
|
||
|
} else {
|
||
|
endPtr--
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|