LeetCode练习题
15. 三数之和
描述
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路
将等式变化一下,即是求满足a+b=-c的三元组,想到之前的两数之和问题,又注意到答案不在乎顺序,因此可先将数组排序,然后从小到大枚举c,然后就可以利用之前的两数之和的双指针法找到a和b。由于我直接照搬了之前的函数,每次需要复制数组,所以肯定比较慢,因此加了一些优化,比如c大于0的时候肯定不会再有解因此终止枚举,使用set存储答案加速判重过程。还有一个优化是用来过最后一个全是0的数据的,可以想到数组中相同的非零数最多只要2个,0最多只要3个即可,因此在排序之后再处理一下数组,减少枚举量。
将复制数组的方式改进后发现时间上的优化不是很大。
代码
class Solution:
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
count = 1
for i in range(len(nums)-2, -1, -1):
if nums[i+1] == nums[i]:
count += 1
else:
count = 1
if (count==3 and nums[i]!=0) or (count==4 and nums[i]==0):
nums.pop(i)
count -= 1
# print(nums)
ans = set()
for i in range(len(nums)):
if nums[i] <= 0:
temps = twoSum(nums, i+1, len(nums), -nums[i])
for temp in temps:
# temp.insert(0, nums[i])
temp = '['+str(nums[i])+','+temp[1:]
if temp not in ans:
ans.add(temp)
else:
break
return list(map(eval, ans))
def twoSum(nums, left, right, target):
differences = {}
ans = set()
for i in range(left, right):
if nums[i] in differences:
temp = str([nums[differences[nums[i]]], nums[i]])
if temp not in ans:
ans.add(temp)
differences[target-nums[i]] = i
return list(ans)