15.三数之和

方法:双指针

这段代码的目标是找到数组中所有满足三数之和为 0 的不重复元素组合,并将其存储在 ans 数组中返回。代码中使用双指针法来遍历数组,通过设定首尾两个指针,逐渐逼近目标值。具体流程如下:

  1. 将数组排序,使得相同的元素相邻。
  2. 外层循环遍历数组中的每个元素,用指针 first 指向当前元素。
  3. 如果当前元素与前一个元素相同,则跳过,以去重。
  4. 内层循环中,使用指针 secondthird 分别指向 first 后面的第一个元素和数组的最后一个元素。
  5. 如果 second 指向的元素与前一个元素相同,则跳过,以去重。
  6. 判断 nums[second] + nums[third] 是否大于目标值 `

  • 时间复杂度:代码中使用了两层循环,外层循环的时间复杂度为 O(n),内层循环根据具体情况可能是 O(n) 或 O(nlogn)。整体来说,时间复杂度为 O(n^2) 或 O(n^2logn)。
  • 空间复杂度:创建了一个二维数组 ans 来存储结果,其空间复杂度与最终结果的数量成正比,所以为 O(n)。
func main(){
	nums3:=[]int{0,0,0,0,0,0,0,1,1,-1,-1,2,0,-2}
	ansMatrix:=threeSum(nums3)
	fmt.Println(ansMatrix)
}

func threeSum(nums []int) [][]int {
	n:=len(nums)
	sort.Ints(nums)//给数组排序
	ans:=make([][]int,0)//创建一个存放三数之和元素的数组的数组
	//
	for first:=0;first<n;first++{
		if first>0&&nums[first]==nums[first-1]{//用nums[first]==nums[first-1]来判断排好序的数组中当前元素是否和上一个元素相等,
			// 如果和上一个元素相等,说明上一层已经遍历过这个元素了,所以就要给不同的三元数组之间去重。
			//continue的意思是如果if满足条件,执行continue,不用继续执行后面的语句,直接进行迭代first++。
			continue
		}
		third:=n-1//定义第三个元素的指针
		target:=-1*nums[first]//定义-a的变量,用-a来判断b+c是否等于-a
		//第二个元素b从first的下一个开始
		for second:=first+1;second<n;second++{//定义第二个元素b的指针,第二个元素不能与第三个元素相加,所以second<third
			//b也是要去重,因为是排好序的数组,相临的两个元素相同的话要去重
			if second>first+1 && nums[second]==nums[second-1] {
				continue
			}
			//b+c>target的话,最大的元素third要减小一点
			for second<third&&nums[second]+nums[third]>target{
				third--
			}
			//如果second层遍历到和third相同的位置了,说明没有找到b+c,而第二个元素不能与第三个元素相加,所以直接结束循环
			//(因为second不动的时候,third会动,所以有可能相等)
			if second==third{
				break
			}
			//每轮second迭代,都把数组存下来
			if nums[second]+nums[third]==target{
				ans=append(ans,[]int{nums[first],nums[second],nums[third]})
			}
		}
	}
	return ans
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值