1、题目
2、题解
1)首先直觉想到暴力解法,即三重循环整个数组,遍历所有可能的三元组,计算其和是否为0。面对不能有相同三元组的情况,也采用了直接遍历一一对比的方式。程序可以跑通,但代价就是由于时间复杂度过高,代码难以通过较长的测试用例,最终提交失败。
代码如下
func threeSum(nums []int) [][]int {
values := [][]int{}
l := len(nums)
if l<3{
return values
}
for key1, value1 := range nums{
for key2:=key1+1; key2<l; key2++{
value2 := nums[key2]
for key3:=key2+1; key3<l; key3++{
value3 := nums[key3]
if value1+value2+value3==0{
r := []int{value1,value2,value3}
if isExit(values, r){
values = append(values,r)
}
}
}
}
}
return values
}
func isExit(a [][]int, b []int) bool{
if len(a) == 0{
return true
}
for _, value := range a{
v := []int{value[0],value[1],value[2]}
for i, v1 := range b{
j := IsContainInt(v, v1)
if j==-1{
break
}
v = append(v[:j], v[j+1:]...)
if i==2{
return false
}
}
}
return true
}
func IsContainInt(items []int, item int) int {
for i, eachItem := range items {
if eachItem == item {
return i
}
}
return -1
}
提交结果如下
2)查看官网题解,果然题目的难度在于如何消除重复的三元组,具体方法如下:
(1)将数组排序,按照顺序遍历获取三元组。
(2)为了防止数组内存在重复的数字,导致三元组出现重复,所以在遍历时要求前后两次遍历的数字不能相同。
补:减小时间复杂度的方法
(1)通过两头指针减小时间复杂度 因为要求a+b+c=0,所以随着遍历当b'>b时,必有c'<c,所以在2重遍历的过程中可同时反方向进行三重遍历。
代码如下:
func threeSum(nums []int) [][]int {
values := [][]int{}
numsLen := len(nums)
first,second,thrid := 0,1,numsLen-1
sort.Ints(nums)
for ; first<numsLen-2; first++{
if first>0 && nums[first-1]==nums[first]{
continue
}
for second, thrid = first+1, numsLen-1; second<thrid; second++{
if second>first+1 && nums[second-1]==nums[second]{
continue
}
for nums[first]+nums[second]+nums[thrid]>0 && thrid>second{
thrid--
}
if nums[first]+nums[second]+nums[thrid]==0 && second<thrid{
r := []int{nums[first],nums[second],nums[thrid]}
values = append(values,r)
thrid--
}
}
}
return values
}
提交结果如下: