【问题标题】:How to make this arrays combination algorithm more efficient?如何让这个数组组合算法更高效?
【发布时间】:2020-02-09 03:39:38
【问题描述】:

到目前为止,我有一个通过 a 的 for 循环,然后是另一个检查 b 值的 for 循环,然后取 c 的最高值并将其放入新数组中


D = [0, 0, 0]
for i in A
    highestToAdd = 0
    for j in B
        if B[j] < A[i]
            if C[j] > highestToAdd 
                highestToAdd = C[j]
    D[i] = highestToAdd
return D
input arrays:
A = [3, 1, 7]
B = [5, 0, 2] 
C = [5, 3, 25]

output array is:
D = [25, 3, 25]

在这里你可以看到我们两次得到了 25,我们不得不多次循环遍历整个 b,以找到 c 中的最大值来找到它。

如您所见,我会一遍又一遍地循环 a 的每个值和 b 的每个值(尤其是当 3 个数组大小增加时),我应该采取什么方向?

编辑 - 更大的样本

A = [5, 2, 1, 9, 3, 1, 5, 4, 2, 2]
B = [8, 1, 7, 10, 6, 2, 5, 2, 4, 3]
C = [9, 5, 8, 4, 6, 10, 3, 9, 6, 8]

would result in
D = [10, 10, 5, 10, 10, 5, 10, 10, 10, 10]

【问题讨论】:

    标签: arrays algorithm performance dynamic pseudocode


    【解决方案1】:

    您可以将 B 的每个元素与其在 C 中的匹配元素相关联,然后按值对组合的 A 和 B 进行排序。

    即,

    A = [3, 1, 7]
    B = [5, 0, 2]
    C = [5, 3, 25]
    sorted = [(0,B,3), (1,A), (2,B,25), (3,A), (5,B,5), (7,A) ]
    

    然后在处理这个问题时,取 C 中匹配元素的最大值,并在到达时将它们与 A 的元素相关联。

    (0,B,3): max = 3
    (1,A): A.1 is associated with 3
    (2,B,25): max = 25
    (3,A): A.3 is associated with 25
    (5,B,5): max = 25
    (7,A): A.7 is associated with 25.
    

    最终答案:[25,3,25]

    运行时间:O(n log n)

    【讨论】:

    • 我很困惑,将 B 的每个元素与 C 中的匹配元素相关联是什么意思?
    • @Casabias 表示将它们保持成对 (0,3), (2,25), (5,5),其中第一个元素来自 B,第二个元素来自 B C. 在哪个答案中,他将 B 放在对中,以装饰它并将它们与 A 的元素区分开来,他用 A 装饰。
    • @Casabias 按第一个组件对它们进行排序。这样 B 的元素被排序,A 的元素也被排序,并且介于 B 的元素比它们前面的元素之间。
    • @Casabias 当您从左到右移动列表时,您会保持最大值。当您到达 A 的元素之一时,您将输出当前最大值。所以,你读到 (0,3)。当前最大值为 3。然后读取 (1),它是 A 的一个元素。输出当前最大值 3。然后读取 (2,25)。当前最大值变为 25。当读取 (3) 时,由于它是 A 中的一个元素,因此输出当前最大值 25。当您读取下一个条目 (5,5) 时,当前最大值不会改变。然后你读(7)。由于它是来自 A 的元素,因此您输出当前最大值,仍然是 25。
    • @Casabias 顺便说一下,您可能会注意到这些值输出为 3、25、25 而不是 25、3、25。但请注意,在输出它们时,您知道 A 的哪个元素与每个输出相关联。您需要将 A 的元素保存在一个结构中,以便您为 A 的每个元素查找其在原始数组中的位置。这可以通过将 A 的元素映射到其在原始 A 中的位置的哈希表来完成。
    【解决方案2】:

    我不确定这个逻辑,但它至少适用于示例测试。

    我按照@Dave 的建议将BC 元素成对存储,并按C 值的降序对列表进行排序。

    现在,我做了类似的事情:对于每个元素 (ci, bi),找到 A 中的所有元素,例如 aj &gt; bi。将jth 位置标记为已访问(以防止稍后重新分配其他ci)并将ci 存储在输出数组中的jth 索引处。

    A = [3, 1, 7]
    B = [5, 0, 2]
    C = [5, 3, 25]
    E = []
    for i in range(len(C)):
        E.append((C[i], B[i]))
    
    E.sort(reverse = True)
    
    D = {}
    visited = [False] * len(B)
    for c, b in E:
        ind = 0
        for a in A:
            if not visited[ind] and a >= b:
                D[ind] = c
                visited[ind] = True
            ind += 1
    
    print(D)
    

    【讨论】:

    • 不确定访问过的,因为 A = [5, 2, 1, 9, 3, 1, 5, 4, 2, 2], B = [8, 1 , 7, 10, 6, 2, 5, 2, 4, 3] 和 C = [9, 5, 8, 4, 6, 10, 3, 9, 6, 8], D 应该 = [10, 10 , 5, 10, 10, 5, 10, 10, 10, 10]
    • @Casabias,有一点小错误,不是a &gt; b,应该是a &gt;= b。然后它适用于给定的较大输入。进行了修改,看看吧!
    • 谢谢!如果数组大小最大为 10 个元素并且每个元素介于 1 到 10 之间,那么对数组进行排序不会比上面的 2 个循环花费更多的时间吗?
    • 有可能,在这种情况下,使用插入排序会有所帮助。我在某处读过较小的数字。元素,插入排序工作得更快。您可以设计一个方法custom_sort() 来检查是否为否。元素个数小于,比如 10,然后进行插入排序,否则使用 sort() 方法。
    • 这很棒,但是经过比较,与 2 个循环的蛮力比较时,排序需要太多纳秒,如果我试图找到 D 的总和,蛮力也很慢相反,整个事情都需要改变吗?到目前为止,我只是将 c 添加到总和中,而不是将其保存到 D 中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    相关资源
    最近更新 更多