所有数组元素都除以每个数组元素的商数之和

时间:2018-11-25 13:56:55

标签: arrays math

在编码测试中遇到一个问题,假设我们有数组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),将使我的元素数量大于所采用的倍数,这将增加最终结果。但这给了我错误的答案。如何有效解决此问题,欢迎提出任何建议。

1 个答案:

答案 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")

礼物:

comparison