题目链接:LC15
这是一道经常做过就忘记的题目,写写博客巩固一下。
题意
- 给定一个数组,要求找出所有三元组,使得三元组的和等于0,且不能有重复的三元组。
思路:排序+双指针
- 对于每一个三元组,假定a<b<c,因为总有最小的那个数字,且顺序不影响答案。所以我们先枚举a
- 先对原数组进行排序
- 对于每一个 a
- 利用双指针,枚举 b 和 c ,令b=a+1,c=n-1,
- 为确保答案不包含重复的值,需要判断nums[b]!=nums[b-1],否则 b++
- 枚举完 a 和 b 后,计算 nums[a]+nums[b]+nums[c] 的值,若大于0,则c--
- 直到三数之和等于0时,将三元组加入数组当中去。
- 若枚举双指针过程中,出现b>=c,则需跳出循环,枚举新的a
代码(Golang)
func threeSum(nums []int) [][]int {
var ans [][]int
sort.Ints(nums)
n:=len(nums)
for i,j:=range nums{
if i>0 && j==nums[i-1]{
continue
}
tar,l,r:=-j,i+1,n-1
for l<r && l<n{
for l<n && l>i+1 && nums[l]==nums[l-1]{
l++
}
for r>l && nums[l]+nums[r]>tar{
r--
}
if l>=r{
break
}
if nums[l]+nums[r]==tar{
ans=append(ans,[]int{j,nums[l],nums[r]})
}
l++
}
}
return ans
}
本题思路上没有大的难点,用暴力也能轻松卡过。但是双指针法能够将时间复杂度从 O(n³) 降低到 O(n²) ,与LC16十分接近,思路上大体一致,但是偶尔过段时间做的时候又会出现一些细节上的小问题。
遗忘是学习最大的敌人。
——刘伟