pseudo code
- i : 기준 포인터 / left, right : 가변 포인터
1. 입력 슬라이스를 정렬합니다.
2. 중복 수가 있으면 끝 수까지 이동하고 끝 수를 기준포인터로 합니다.
3. i를 슬라이스의 크기 -2 만큼 반복합니다. (이유 : 3개의 포인터 사용)
3-1. i를 기준으로 다음 수를 left, 슬라이스의 끝 수를 right로 합니다.
3-2. left가 right보다 작을 조건으로 반복
3-2-1. 세수의 합을 구합니다.
3-2-2. 합이 작으면 left를 우측으로 한칸, 크면 right를 좌측으로 한칸, 같으면 다른 슬라이스에 세수를 넣습니다.
3-2-3. left와 right도 중복제거작업을합니다.
3-2-4. 중복작업 후 left를 우측한칸, right를 좌측한칸으로 이동시킵니다.
4. 세수가 추가된 슬라이스를 return합니다.
Code
package main
import (
"fmt"
"sort"
)
func threeSum(nums []int) [][]int {
var results [][]int
// 정수 슬라이스 정렬
sort.Ints(nums)
for i := 0; i < len(nums)-2; i++ {
// 중복 스킵 (기준포인터)
if i > 0 && nums[i] == nums[i-1] {
continue
}
var left, right int = i + 1, len(nums) - 1
for left < right {
sum := nums[i] + nums[left] + nums[right]
if sum < 0 {
left++
} else if sum > 0 {
right--
} else { // sum == 0
results = append(results, []int{nums[i], nums[left], nums[right]})
// left, right 중복제거
for left < right && nums[left] == nums[left+1] {
left++
}
for left < right && nums[right] == nums[right-1] {
right--
}
left++
right--
}
}
}
return results
}
func main() {
var nums = []int{-1, 0, 1, 2, -1, -4}
result := threeSum(nums)
fmt.Println(result)
}