tags:
- 三层循环
- 双指针
题目
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
###解法一:暴力法
拿到题目首先想到之前做过的两数之和,就是遍历所有的可能组合,保存满足条件的组合并去除重复的组合即可。这题是三数之和所以需要用到三重循环。实现如下:
def threeSum(nums: List[int]):
answer = []
nums.sort()
for x in range(len(nums)):
for y in range(x+1,len(nums)):
for z in range(y+1,len(nums)):
if nums[x]+nums[y]+nums[z] == 0:
temp=[nums[x],nums[y],nums[z]]
if temp not in answer:
answer.append(temp)
return answer
测试简单用例可以通过,但是提交时显示超过时间限制。于是去翻题解大佬们的解法,记录如下。
解法二:排序+双指针
def threeSum(nums: List[int]):
ans=[] #用来保存结果的列表
if(not nums or len(nums)<3): #排除列表为空或元素数小于3的特例
return []
nums.sort() #有小到大排序方便后续的判断
for i in range(len(nums)):
if(nums[i]>0): #如果最小的i大于0,那么肯定无法找到满足条件的结果
return ans
if(i>0 and nums[i]==nums[i-1]): #如果当前元素与上个元素相同,则结果肯定重复,可以跳过
continue
L=i+1 #设定左指针
R=len(nums)-1 #设定右指针
while(L<R): #循环判断
if(nums[i]+nums[L]+nums[R]==0): #当满足条件时保存结果进ans中
ans.append([nums[i],nums[L],nums[R]])
while(L<R and nums[L]==nums[L+1]): #去除重复结果
L=L+1
while(L<R and nums[R]==nums[R-1]): #去除重复结果
R=R-1
L=L+1
R=R-1
elif(nums[i]+nums[L]+nums[R]>0): #当结果大于0时,说明右指针元素过大,移动右指针
R=R-1
else: #当结果小于0时,说明左指针元素过小,移动左指针
L=L+1
return ans
解法是借鉴题解中的大佬写得,注释由个人理解所写。