解法:排序 + 双指针
- 首先对数组排序,便于后面处理重复元素。
- 第一层循环遍历数组中的每一个元素,作为三元组中的第一个元素 nums[i] ,并跳过重复的元素。
- 对于每个 i ,使用双指针 l (初始为 i+1)和 r (初始为数组末尾),在 i 之后的区间寻找满足 nums[l]+nums[r] 等于 -nums[i]。
根据双指针指向的两数之和与目标值( -nums[i] )的大小关系:如果相等,将对应的三元组添加到结果数组中,移动指针,并跳过重复元素;如果小于target,左指针 l 右移;如果大于target,右指针 r 左移。
func threeSum(nums []int) [][]int {sort.Ints(nums)result := [][]int{}length:=len(nums)for i := 0;i<length;i++{//跳过重复元素if i>0&&nums[i]==nums[i-1]{continue}target:=-nums[i]l,r:=i+1,length-1for l<r {sum := nums[l]+nums[r]if sum == target {result=append(result,[]int{nums[i],nums[l],nums[r]})l++r--//跳过重复元素for l<r && nums[l]==nums[l-1]{ l++ }for l<r && nums[r] == nums[r+1]{ r-- }}else if sum<target {l++}else{r--}}}return result
}
时间复杂度:排序 O(nlogn),循环 O(n2),总体 O(n2)。
空间复杂度:排序 O(logn),result数组排序 O(n2),总体排序 O(n2)。
我一开始的想法:
- 首先对数组排序,便于后面处理重复元素。
- 第一层循环遍历数组中的每一个元素,作为三元组中的第一个元素 nums[i] ,并跳过重复的元素。
- 第二层循环遍历 i 之后的元素作为三元组的第二个数 nums[j],同样跳过重复的元素。
- 第三层循环遍历 j 之后的元素,找到满足条件的第三个数 nums[m],将对应的三元组添加到结果 result 中,并跳出内层循环。
func threeSum(nums []int) [][]int {sort.Ints(nums)result := [][]int{}length:=len(nums)
//解法一for i:=0;i<length;i++{if i>0 && nums[i] == nums[i-1]{continue}n := -nums[i]for j:=i+1;j<length;j++{if j>i+1 && nums[j]==nums[j-1]{continue}k:= n-nums[j]for index,v := range nums[j+1:] {if v == k {m := index+j+1result=append(result,[]int{nums[i],nums[j],nums[m]})break}}}}return result
}
时间复杂度:排序 O(nlogn),循环O(n3),总体O(n3)。
空间复杂度:排序 O(logn),存储结果的result二维数组O(n2),总体O(n2)