题目描述:给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。
样例:如S = {-1 0 1 2 -1 -4}, 你需要返回的三元组集合的是:(-1, 0, 1),(-1, -1, 2)
可以先对整个数组排序,然后依次取数组中的元素,固定,再检查从这个元素之后的那个元素开始,直到数组结尾的部分中,存不存在两个数的和,恰好是固定元素的相反数。
比如,样例中,先排序,得到[-4, -1, -1, 0, 1, 2],取-4固定,检查后面的部分,发现不存在哪两个数的和是4;再取-1固定,检查后面的部分,发现0 + 1 = 1,合适,结果列表中应当出现[-1, 0, 1]...依次向后进行即可。检查后面部分数组是否存在两数之和满足条件的方法就是我们之前做过的两数之和(详见:点击打开链接),但是,当时我们解决这个问题用的是哈希表,为了在此处不增加额外空间,我们对两数之和的处理采用新的左右逼近的方法(详见下面的代码)
但是这个里面会有个问题,那就是可能出现重复,而题目的要求是不能重复的,所以,既然我们用的是Python,就完全可以利用Pyhon中“集合”的特性去重。
代码如下:
class Solution:
"""
@param numbersbers : Give an array numbersbers of n integer
@return : Find all unique triplets in the array which gives the sum of zero.
"""
def threeSum(self, numbers):
result = set()
n = len(numbers)
index = 0
numbers.sort()
while index < n - 2:
target = numbers[index]
begin = index + 1
end = n - 1
self.two_sum(numbers, target, begin, end, result)
index += 1
return list(result)
def two_sum(self, numbers, target, begin, end, result):
left = begin
right = end
while left < right:
if numbers[left] + numbers[right] == -target:
result.add((numbers[begin - 1], numbers[left], numbers[right]))
while left < right and numbers[left] == numbers[left + 1]:
left += 1
while left < right and numbers[right] == numbers[right - 1]:
right -= 1
left += 1
right -= 1
elif numbers[left] + numbers[right] > -target:
while left < right and numbers[right] == numbers[right - 1]:
right -= 1
right -= 1
else:
while left < right and numbers[left] == numbers[left + 1]:
left += 1
left += 1
# write your code here
后面的函数two_sum()是处理两数之和的,左右逼近法,参数比较多,target是之前固定的数,begin, end是需要检查的部分的起始及结束的位置,result是一个集合,往result里面添加的元素是元组(Python中,元组这种可hash的类型才能为集合所用)