2024/10/12 力扣 15.三数之和
15.三数之和
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1] 输出:[] 解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0] 输出:[[0,0,0]] 解释:唯一可能的三元组和为 0 。
当问题中变量较多时,常考虑固定某个变量,此题采用固定首个数去找另外两个数的方法
每次固定一个数,就会直接将该数的所有组合找完,所以与固定的数重复的值可直接跳过
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
ts = []
n = len(nums)
# 每次固定三个数中的首个数,找其余两数
for i in range(n-2):
# 每次会将固定了的数的所有搭配找完,所以有重复值时直接跳过
if i > 0 and nums[i]==nums[i-1]:
continue
# 列表已排序,前三个数为最小的数,若最小的数相加都大于0,则无数相加==0
if nums[i] + nums[i+1] + nums[i+2] > 0:
break
# 列表已排序,最后两数为最大的数,若最大的两个数与前面的数相加都小于0,则直接找其它数
if nums[i] + nums[-1] + nums[-2] < 0:
continue
j = i + 1
k = n-1
while j < k:
s = nums[i] + nums[j] + nums[k]
if s > 0:
k-=1
elif s < 0:
j+=1
else:
ts.append([nums[i],nums[j],nums[k]])
j += 1
while j < k and nums[j]==nums[j-1]:
j+=1
k-=1
while j < k and nums[k]==nums[k+1]:
k-=1
return ts