解法:排序 + 雙指針
- 首先對數組排序,便于后面處理重復元素。
- 第一層循環遍歷數組中的每一個元素,作為三元組中的第一個元素 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)