三数之和
三数之和
题目描述:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
思路分析
三数之和来自于两数之和的扩展,但两数之和那个题,题目保证只有一种结果,找到则返回即可。而三数之和要找到所有的结果,所以是无法直接复用两数之和的代码的。并且这个题要求是不可以包含重复三元组,如何才能不重复地获得数据呢,我采用的方式是排序+遍历+双指针。
这一题我认为我的代码是算又臭又长的了,所以一定要先看思路,看懂之后自己写无非也就那样,就不会被看起来很麻烦的代码劝退了:
首先对数组进行排序,当然只要涉及到排序操作,时间复杂度最低也是nlogn了。可以自己写个快排,也可以直接使用sort(因为这里排序并不是重点,偷个懒也并不太影响)。
对数组进行排序之后,我们从头开始遍历整个排序数组,把当前遍历到的值作为第一个数,并对当前位置往后的数组范围做两数之和的处理。这样一来,数组中的每一个数(除了倒数两个)都被当作过第一个数来对待,可以充分考虑到所有情况,并且因为只考虑这个数位置往后的数组,也不会造成重复的现象。
对于处理两数之和问题,因为已经说明了无法复用之前的代码,所以要采取另一种方式:也就是在盛最多水的容器题目中用到的双指针。具体思路直接看代码吧,其实也还是从两边向中间靠拢的过程而已。
代码:
class Solution(object):
def threeSum(self, nums):
def two_sum(nums,target):#先定义两数之和的函数
#用双指针,否则超时
i = 0#i代表左指针
lenth = len(nums)#总长度
j = lenth-1#j代表右指针
res = []#存放结果,因为我们要找到所有结果,所以要把结果都存起来
while i<j:#当左右指针未相遇时
summ = nums[i]+nums[j]
if summ==target:
#假设二者之和等于目标值,以列表的形式添加进res
res.append([nums[i],nums[j]])
#找到目标之后 ,还要继续缩进
#左
now_i = nums[i] #暂存一下当前的值
#左指针向右移动,这里因为可能会有重复的值,所以要一直移动到与当前值不同的位置
while i<j and nums[i]==now_i:
i+=1
#右
#右指针向左移动,也是一样,移到下一个不同的位置处
now_j = nums[j] #暂存一下当前的值
while i<j and nums[j]==now_j:
j-=1
#若sum比target小,则只需要移动左指针就好了,因为左指针向右移动,可以让和慢慢变大。这就是排序的作用。
elif summ<target:
now_i = nums[i]
while i<j and nums[i]==now_i:
i+=1
#若sum比target大,则只需移动右指针即可,原因同理。
elif summ>target:
now_j = nums[j]
while i<j and nums[j]==now_j:
j-=1
return res#最终,res里就是一对对和为target的列表。
left = 0#回到外面,我们定义left为0,开始遍历整个数组
lenth=len(nums)
total_res=[]#存放总结果
nums.sort()#使用sort进行排序,这个是必须操作。
#所以后面传入two_sum的函数,也是排序过的有序数组。
while left<lenth-2:#left一直遍历到倒数第二个
#(因为至少要留两个给twoSum函数)
rs = two_sum(nums[left+1:],-nums[left])#以-nums[left]作为target
if rs:#如果返回的rs有值,其实就是一个个列表
for r in rs:
#遍历每一个列表,加上当前的nums[left]就组成了其中一个结果
r.append(nums[left])
total_res.append(r)
now_left=nums[left]#暂存一下当前的值
#更新移动left,也是移动到下一个值不同的位置为止
while left<lenth-2 and nums[left]==now_left:
left+=1
return total_res
这样子,就可以既全面,又不会重复且不会超时地找到所有三元组了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了