在编码测试中遇到一个问题,假设我们有数组arr = [4,3,8]
。将数组除以4得到1(4/4)+ 0(3/4)+ 2(8/4)=3。类似地,将3除以4得到4,而将8除以1。因此输出为3 + 4 + 1 = 8 O(n2)
解决方案获得了TLE,所以我试图做得更好。
我想到了排序和使用下限。 arr[i]*k
的下界,对于k = 1,2,3...
,直到arr[i]*k<=max(arr)
,将使我的元素数量大于所采用的倍数,这将增加最终结果。但这给了我错误的答案。如何有效解决此问题,欢迎提出任何建议。
答案 0 :(得分:0)
如果我正确理解了您的问题,则(在此示例中)您需要三个数组,它们是原始数组除以其三个元素中的每一个(用整数除法),然后求和。
arr = [4,3,8]
sum([el//i for i in arr for el in arr])
会给您想要的结果。为了理解,结果列表为:
In [8]: [el//i for i in arr for el in arr]
Out[8]: [1, 0, 2, 1, 1, 2, 0, 0, 1]
对此求和得出结果8
。如果您确实需要以这种方式将三个数组分开而不是串联在一起,那么我将编辑此答案。
EDIT (抱歉),所以我误解了这个问题。如果允许使用numpy,我建议使用此算法,该算法(我认为)仍然是O(n²),但总体上要快得多:
arr = np.random.randint(1,10,n)
np.sum(np.tile(arr, n)//np.repeat(arr,n))
也许明天我可以想出一些更聪明的东西
编辑2 排序实际上是一个好主意,可以稍微加快算法的速度。到目前为止,我已经使用此脚本测试了三种解决方案(我知道time.time
不能满足确切时间的要求,但是它仅显示了每种算法的一般速度):
for n in range(100, 500):
arr = np.random.randint(1,10,n)
#sorted
t = time.time()
arr2 = sorted(arr)
sum([el1//el2 for i, el2 in enumerate(arr2) for el1 in arr2[i:]])
t2 = time.time()-t
times_sorted.append(t2)
#standard
t = time.time()
arr = sorted(arr)
sum([el1//el2 for el2 in arr for el1 in arr])
t2 = time.time()-t
times_standard.append(t2)
#numpy
t = time.time()
arr = sorted(arr)
np.sum(np.tile(arr, n)//np.repeat(arr, n))
t2 = time.time()-t
times_numpy.append(t2)
if not n%50:
print(n)
绘图
plt.figure()
plt.plot(times_numpy)
plt.plot(times_sorted)
plt.plot(times_standard)
plt.legend(["numpy", "sorted", "standard"])
plt.xlabel("n")
plt.ylabel("time in s")
礼物: