📅  最后修改于: 2023-12-03 15:12:05.006000             🧑  作者: Mango
在一个整数数组中,寻找三个数,使它们的乘积为0,即其中至少有一个数为0。本文将介绍几种解决该问题的方法。
暴力枚举所有的三元组,判断是否满足要求。时间复杂度为$O(n^3)$,空间复杂度为$O(1)$。
def threeNumsWithZeroProduct(nums: List[int]) -> List[List[int]]:
n = len(nums)
res = []
for i in range(n):
for j in range(i+1, n):
for k in range(j+1, n):
if nums[i]*nums[j]*nums[k] == 0:
res.append([nums[i],nums[j],nums[k]])
return res
利用哈希表存储数组中所有数及其出现次数,之后枚举数组中的两个数,判断它们的乘积是否等于另一个数的相反数。时间复杂度为$O(n^2)$,空间复杂度为$O(n)$。
def threeNumsWithZeroProduct(nums: List[int]) -> List[List[int]]:
n = len(nums)
res = []
if n<3:
return res
count = defaultdict(int)
for num in nums:
count[num] += 1
for i in range(n-1):
for j in range(i+1, n):
if nums[i]*nums[j] == 0:
if nums[i] == nums[j] and count[nums[i]] >=3:
res.append([nums[i],nums[j],0])
elif nums[i] == 0 and count[nums[j]] >= 2:
res.append([nums[i],nums[j],0])
elif nums[j] == 0 and count[nums[i]] >= 2:
res.append([nums[i],nums[j],0])
elif count[-nums[i]-nums[j]]>=1:
res.append([nums[i],nums[j],-nums[i]-nums[j]])
return res
首先对数组进行排序,使用双指针的思路,枚举数组中的一个数,之后从它后面的数中使用双指针查找是否存在两个数的乘积等于它的相反数。时间复杂度为$O(n^2)$,空间复杂度为$O(1)$。
def threeNumsWithZeroProduct(nums: List[int]) -> List[List[int]]:
n = len(nums)
res = []
nums.sort()
for i in range(n-2):
if nums[i]>0:
break
if i>0 and nums[i]==nums[i-1]:
continue
left, right = i+1, n-1
while left<right:
mul = nums[left]*nums[right]
if mul== -nums[i]:
res.append([nums[i],nums[left],nums[right]])
left += 1
right -= 1
while left<right and nums[left]==nums[left-1]: left+=1
while left<right and nums[right]==nums[right+1]: right-=1
elif mul< -nums[i]:
left += 1
else:
right -= 1
if 0 in nums:
count = [num for num in nums if num == 0]
if len(count)>=3:
res.append([0,0,0])
for i in range(n-1):
if nums[i] != 0:
break
if nums[i]==0 and nums[i+1]!=0:
for j in range(i+1, n):
if nums[j] == 0:
res.append([0,0,nums[i]])
break
break
return res
以上三种方法均可以用来计算给定数组中具有乘积0的三元组,哈希表相比前两种方法具有更好的时间复杂度,但需要额外的空间存储哈希表。排序加双指针方法在空间上更省,但需要先进行排序,时间复杂度与哈希表相同。
注:以上代码是在使用了Python中的类型提示(@typing)时编写的,其中使用到的内置函数不再阐释。