Files
2026-05-31 01:09:31 +10:00

77 lines
1.4 KiB
Go

package top100liked
import (
"fmt"
"sort"
"testing"
)
// https://leetcode.cn/problems/3sum/?envType=study-plan-v2&envId=top-100-liked
func threeSum(nums []int) [][]int {
sort.Ints(nums)
n := len(nums)
res := make([][]int, 0)
for i := 0; i < n-2; i++ {
// 去重第一个数
if i > 0 && nums[i] == nums[i-1] {
continue
}
// 剪枝:当前最小三数和已经大于 0
if nums[i]+nums[i+1]+nums[i+2] > 0 {
break
}
// 剪枝:当前最大三数和仍然小于 0
if nums[i]+nums[n-2]+nums[n-1] < 0 {
continue
}
target := -nums[i]
l, r := i+1, n-1
for l < r {
sum := nums[l] + nums[r]
if sum == target {
res = append(res, []int{nums[i], nums[l], nums[r]})
leftVal := nums[l]
rightVal := nums[r]
// 命中后,左右都跳过重复值
for l < r && nums[l] == leftVal {
l++
}
for l < r && nums[r] == rightVal {
r--
}
} else if sum < target {
leftVal := nums[l]
// 当前 l 太小,且重复的 l 也一样太小,直接跳过
for l < r && nums[l] == leftVal {
l++
}
} else {
rightVal := nums[r]
// 当前 r 太大,且重复的 r 也一样太大,直接跳过
for l < r && nums[r] == rightVal {
r--
}
}
}
}
return res
}
func TestS6(t *testing.T) {
nums := []int{-100, -70, -60, 110, 120, 130, 160}
fmt.Printf("%+v", threeSum(nums))
}