注:
本系列文章仅是作者自己学习过程中记录的笔记,是初学python用于算法求解的过程,会含有很多对于python的个人注解,用于学习。求职中解算法,我打算使用Python来进行解答,不知是否可不可以,希望能得到大佬的建议,轻喷。
题目:
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
双指针法:
利用排序思想,来跳过重复解
利用双指针思想,然后用两个指针 left 和 right 在 i+1 ~ n-1 区间内寻找另外两个数。
判断 nums[i] + nums[left] + nums[right]:
-
如果等于
0,就保存结果,并且 跳过重复值。 -
如果小于
0,说明和太小,left += 1。 -
如果大于
0,说明和太大,right -= 1。
时间复杂度:O(N^2)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
res = []
n = len(nums)
for i in range(n - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue # 跳过重复的第一个数
left, right = i + 1, n - 1 # 设置左右指针
while left < right:
sum = nums[i] + nums[left] + nums[right]
if sum == 0:
res.append([nums[i], nums[left], nums[right]]) #将一个列表a添加到一个列表A中,a列表作为A列表一个元素
while left < right and nums[left] == nums[left + 1]:
left += 1 # 跳过重复的 left
while left < right and nums[right] == nums[right - 1]:
right -= 1 # 跳过重复的 right
left += 1
right -= 1 # 移动指针
elif sum < 0:
left += 1
else:
right -= 1
return res
#for i in range(n - 2) —— 为什么是 n-2?-----------我们要找三元组,i要保证后面至少有两个元素可用(left 和 right),所以 i 最后可以取到 n-3
#if i > 0 and nums[i] == nums[i - 1]: continue —— 为什么要跳过相同的 nums[i]?-----------如果不跳过相同的第一个数nums[i],当 nums[i] 和前一个相同(比如 nums[0]==nums[1]==-1),你会重复枚举同样的“以 -1 开头”的所有三元组,导致结果里出现重复项。

被折叠的 条评论
为什么被折叠?



