LeetCode006:三数之和

一、写在前面

LeetCode刷题专栏,欢迎关注
今天给大家分享的是LeetCode 数组与字符串 第六题:三数之和,为面试而生,期待你的加入。

二、今日题目

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:
答案中不可以包含重复的三元组。

示例:

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

三、 分析

看到这个题目第一眼,我想到的就是两数之和,咋一眼感觉上没有太大区别,实际是二维空间和三维空间的区别,最开始想的是和两数之和方法类似,这里我只要找到两数之和的相反数是不是在列表就行了,但真的实践起来,比较麻烦,时间复杂度先不说,就是思想上随便一说都是个麻烦事情,所以X先生果断放弃了这样掉头发不讨好的方法,换了一种思想,头+尾搜索法:头部循环,尾部从两端向中间搜索,思想如下:
我的思想

四、解题

  • 我的方法:
    从从中心向外扩散,时间复杂度:小于O(n^2)
class Solution(object):
    def threeSum(self, nums):
		"""
		:type nums: List[int]
		:rtype: List[List[int]]
		"""
		# 列表排序,从小到大
		nums.sort()
		# [-4, -1, -1, 0, 1, 2]
		res_list = []
		# 头部循环查找
		for i in range(len(nums)):
			if i == 0 or nums[i] > nums[i - 1]:
				# 最左端
				l = i + 1  
				# 最右端
				r = len(nums) - 1
				while l < r:  # 正在查找
					three_sum = nums[i] + nums[l] + nums[r]
					if three_sum == 0:
						res_list.append([nums[i], nums[l], nums[r]])
						l += 1 # 右移一位
						r -= 1 # 左移一位
						while l < r and nums[l] == nums[l - 1]:
							# 从左往右,相同数值直接跳过
							l += 1
						while r > l and nums[r] == nums[r + 1]:
							# 从右往左,相同数值直接跳过
							r -= 1
					elif three_sum > 0:
						# 大于零,右边数值大,左移
						r -= 1
					else:
						# 小于零,左边数值小,右移
						l += 1
		return res_list
  • 提交结果

提交结果

测试数据:313组
运行时间:740ms
击败人百分比:81.35%

五、疑惑

这里说一下上一篇最长公共前缀大牛方法中的zip()。

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,
需手动 list() 转换。

六、结语

坚持 and 努力 : 终有所获。

欢迎大家关注微信公众号:极简XksA,获取Python/Java/前端等学习资源!

极简XksA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简说Python

多多少少都是爱,感谢充电。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值