题目描述:
思路解析:利用双指针
给定数组中的值为乱序,先用 sort() 函数将其进行排序,变为有序数组。
题目中给定三数之和为 0,即 target = 0。a 为最小数的索引,b=a+1,c=n-1,b 从 a 后一个数开始搜索,c 从数组中最后一个数向前搜索。
首先进行判断,如果数组中指针 a 对应的数 nums[a] 比 0 还大,说明后面的 b 和 c 均大于 0,其和不可能为 0,此时停止程序运行。
在 a 满足条件的情况下,再分别对 b 和 c 进行判断。
注:结果中不可以包含重复的三元组。
所以只有 a 的值可以重复,b 和 c 的值不可以重复。
代码:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
result = [] # 定义空数组
n = len(nums) # 数组长度
nums.sort() # 对数组进行排序
for a in range(n-2): # 双指针
if nums[a]>0: # 有序数组中最小的都大于0,则停止
break
if a > 0 and nums[a] == nums[a-1]: # 如果指针a>0,并且a的值和前一个数相等,则继续
continue # 此处已经考虑了重复值,所以对于b、c无需再考虑重复值
b,c = a+1, n-1
while b<c:
target = nums[a] + nums[b] + nums[c] # 定义三数之和为target
if target == 0:
result.append([nums[a], nums[b], nums[c]]) # 三个数相加为0,则将此数组添加到结果列表中
b += 1 # b的指针加1
c -= 1 # c的指针减1
while b<c and nums[b]==nums[b-1]: # 如果b的指针<c的指针,并且b的值和前一个值相等
b += 1 # 重复数字不考虑。b加1,相当于跳过该数
while b<c and nums[c]==nums[c+1]:
c -= 1 # 同理,如果b的指针<c的指针,并且c的值和后一个值相等,则c减1,相当于跳过该数
elif target > 0:
c -= 1 # 三数之和>0,说明要继续寻找更小的数,则c减1
else:
b += 1 # 否则,三数之和小于0,说明要继续寻找更大的数,则b加1
return result