Python 3Sum-时间复杂度
给定一个由n个整数组成的数组nums,nums中是否有元素a、b、c使得a+b+c=0?查找数组中所有唯一的三元组,该数组的和为零 注: 解决方案集不得包含重复的三元组 例如:Python 3Sum-时间复杂度,python,arrays,Python,Arrays,给定一个由n个整数组成的数组nums,nums中是否有元素a、b、c使得a+b+c=0?查找数组中所有唯一的三元组,该数组的和为零 注: 解决方案集不得包含重复的三元组 例如: Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ] 这是我的密码: class Solution: def threeSum(self, nums: List[int]) -&
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
这是我的密码:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
firstPointer = 0
if len(nums) ==0:
return []
sum = 0
sum = nums[0]
numDict = {}
result = []
for i in nums:
numDict[i] = numDict.get(i,0)+1 //Adding to Dict
while firstPointer<len(nums):
sum = nums[firstPointer]
for index, value in enumerate(nums):
if -(sum+value) in numDict and index!=firstPointer and index!=nums.index(-sum-value) and firstPointer!=nums.index(-sum-value):
add = [sum,nums[index],-(sum+value)] //Removing Duplicates
add.sort()
if add not in result:
result.append(add)
firstPointer+=1
return result
类解决方案:
def threeSum(self,nums:List[int])->List[List[int]:
firstPointer=0
如果len(nums)==0:
返回[]
总和=0
总和=nums[0]
numDict={}
结果=[]
对于nums中的i:
numDict[i]=numDict.get(i,0)+1//添加到Dict
而firstPointer可以与np.sort
和np.unique
一起使用:
from itertools import combinations
使用@lenik方法的备选方案:
l = []
ordered_arr = list(sorted(array_nums))
for i,val1 in enumerate(ordered_arr):
if val1>0:
break
for val2 in ordered_arr[i+1:len(array_nums)-1]:
sum1 = val1 + val2
if sum1>0:
break
for val3 in ordered_arr[i+2:len(array_nums)]:
tup = (val1, val2, val3)
if (sum1 +val3) ==0 :
l.append(tup)
list(set([tuple(sorted(comb)) for comb in l]))
测试
import numpy as np
np.random.seed(0)
array_nums = np.random.randint(-100 , 100, 400).tolist()
时间:
时间:
时间:
对于一个更简单的问题,如a+b=0
的解决方案对于预排序数组需要一个线性的O(N)时间,如果需要先对其排序,则需要O(NlogN)时间。下面是一个计划,您将数组按O(NlogN)排序,然后执行以下操作:
取第一个元素,命名为“C”,在线性时间内求解a+b=-C
取另一个元素,将其命名为“C”
继续,直到数组中的所有元素都用完为止
总的来说,这将给你O(N^2)复杂度。你认为nums.index
需要多长时间?它返回第一个检出的元素的索引,所以我猜是O(N)top?嗯,我明白你的意思了。那么这里的复杂性是n^4@user2357112supportsMonica提供了三种方法的描述和代码,其中两种是O(n^2)。@DarrylG我知道这一点。我想知道我的代码花费了多少时间,以及为什么这会如此惊人。但地图在这里的意义是什么?如果它是一个列表,为什么.tolist()在那之后?请纠正我,但是组合(…,3)
的复杂性是O(N^3)?映射到这里,对数组的每个元素应用一个函数并返回一个迭代器,tolist
,以便将np.array
转换为列表
l = []
ordered_arr = list(sorted(array_nums))
for i,val1 in enumerate(ordered_arr):
if val1>0:
break
for val2 in ordered_arr[i+1:len(array_nums)-1]:
sum1 = val1 + val2
if sum1>0:
break
for val3 in ordered_arr[i+2:len(array_nums)]:
tup = (val1, val2, val3)
if (sum1 +val3) ==0 :
l.append(tup)
list(set([tuple(sorted(comb)) for comb in l]))
import numpy as np
np.random.seed(0)
array_nums = np.random.randint(-100 , 100, 400).tolist()
%%timeit
np.unique(list(map(np.sort,filter(lambda x: sum(x)==0,
combinations(array_nums,3)))),
axis=0).tolist()
2.93 s ± 136 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
list(set([tuple(sorted(comb))
for comb in filter(lambda x: sum(x)==0,
combinations(array_nums,3))]))
2.66 s ± 66.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
l = []
ordered_arr = list(sorted(array_nums))
for i,val1 in enumerate(ordered_arr):
if val1>0:
break
for val2 in ordered_arr[i+1:len(array_nums)-1]:
sum1 = val1 + val2
if sum1>0:
break
for val3 in ordered_arr[i+2:len(array_nums)]:
tup = (val1, val2, val3)
if (sum1 +val3) ==0 :
l.append(tup)
list(set([tuple(sorted(comb)) for comb in l]))
1.34 s ± 87.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)