15. 三数之和
原始题目链接:https://leetcode-cn.com/problems/3sum/
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
解题思路:
先判断边界条件,数组是否存在,是否包含至少3个元素,边界条件都判断完后,再将数组排序,然后遍历数组中的元素,每遍历一个元素的同时,设置第二个数和第三个数分别为当前遍历的第一个元素的后面的元素和最后的元素,同时判断三数之和是否为0,满足则加入到结果数组中,在判断的同时进行去重操作,减少不必要的计算。具体实现看代码及注释。
代码实现:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
length = len(nums)
if (not nums or length < 3):
return []
res = []
# 排序数组
nums.sort()
for i in range(length):
# 如果此时遍历到的nums[i]已经大于0了,因为数组是排好序的,后面不可能有比nums[i]更小的了
# 直接返回结果即可
if nums[i] > 0:
return res
if (i > 0 and nums[i - 1] == nums[i]):
continue
# 当前第一个数是nums[i], 开始设置遍历的第二个数和第三个数索引坐标
l = i + 1
r = length - 1
# 开始遍历
while l < r:
# 满足条件就加入到结果数组中
if (nums[i] + nums[l] + nums[r] == 0):
res.append([nums[i], nums[l], nums[r]])
# 判断重复,去除不必要的计算
while (l < r and nums[l] == nums[l + 1]):
l += 1
while (l < r and nums[r] == nums[r - 1]):
r -= 1
# 去重后,第二个数和第三个数的坐标索引分别自增1和自减1,进行下一个三数之和的判断
l += 1
r -= 1
# 三数之和大于0,因为数组拍好序了,所以表示右边的数字有点大,将右边的坐标左移
elif (nums[i] + nums[l] + nums[r] > 0):
r -= 1
# 三数之和小于0,因为数组拍好序了,所以表示左边边的数字有点小,将作边的坐标右移
else:
l += 1
return res
参考文献:
https://leetcode-cn.com/problems/3sum/solution/pai-xu-shuang-zhi-zhen-zhu-xing-jie-shi-python3-by/