题目描述:
15. 三数之和
给你一个包含 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]
输出:[]
代码:
class Solution:
def threeSum(self, nums: list) -> list:
nums.sort()
res = []
n = len(nums)
for k in range(n-2):
if nums[k] > 0 :
break
if k > 0 and nums[k] == nums[k-1]:
continue
i = k+1
j = n-1
while i < j:
sum = nums[i]+nums[j]+nums[k]
if sum < 0:
i += 1
elif sum > 0:
j -= 1
else:
res.append([nums[k], nums[i], nums[j]])
i += 1
j -= 1
while i < j and nums[i] == nums[i-1]:
i += 1
while i < j and nums[j] == nums[j+1]:
j -= 1
return res
if __name__ == '__main__':
s = Solution()
print(s.threeSum([-2,0,3,-1,4,0,3,4,1,1,1,-3,-5,4,0]))
解题思路:
排序+双指针
基本思路:首先对数组进行排序,然后从下标k = 0开始,指针i = k+1,j = n-1,判断和是否为0,如果小于0,则i+1(因为数组是排过序的,所以sum<0说明选取的i对应的值太小,应该选取更大的数)。类似的,如果sum>0,则j-1。如果sum=0,则把对应的值加入到结果中,并执行i+1,j-1,选取下一组数。
去重:对于k,如果nums[k] = nums[k-1],则直接进行下一轮循环,选取下一个数。对于i和j,当sum = 0时,执行完i+1和j-1后,判断nums[i]是否等于nums[i-1],即当前i对应的值是否和上一个已经判断过的值相等,如果相等,则跳过,执行i+1。对于j,判断nums[j]是否等于nums[j+1],相等则执行j-1。这里判断重复需要注意是与上一个状态比较,而不是与后一个状态比较。
优化:因为数组是排过序的,所以当第一个数大于0时,将找不到和为0的三元组,直接跳出循环。