【问题标题】:Rearrange an array A so that A wins maximum number of comparisons with array B when comparison is done one-on-one重新排列数组 A,以便在一对一比较时 A 赢得与数组 B 的最大比较次数
【发布时间】:2020-08-19 03:15:00
【问题描述】:

假设我有一个数组 A = [3, 6, 7, 5, 3, 5, 6, 2, 9, 1]B = [2, 7, 0, 9, 3, 6, 0, 6, 2, 6]

重新排列数组 A 的元素,这样当我们按元素进行比较时,例如 3 与 2 以及 6 与 7 等等,我们将获得最大的胜利(A[i] > B[i] 是最大 (0<=i<len(A)) 的组合)。

我尝试了以下方法:

def optimal_reorder(A,B,N):
    tagged_A = [('d',i) for i in A]
    tagged_B = [('a',i) for i in B]
    merged = tagged_A + tagged_B
    merged = sorted(merged,key=lambda x: x[1])
    max_wins = 0
    for i in range(len(merged)-1):
        print (i)
        if set((merged[i][0],merged[i+1][0])) == {'a','d'}:
            if (merged[i][0] == 'a') and (merged[i+1][0] == 'd'):
                if (merged[i][1] < merged[i+1][1]):
                    print (merged[i][1],merged[i+1][1])
                    max_wins += 1
    return max_wins

引用自
here 但是对于给定的 A 和 B,这种方法似乎没有给出正确的答案,即如果 A = [3, 6, 7, 5, 3, 5, 6, 2, 9, 1]B = [2, 7, 0, 9, 3, 6, 0, 6, 2, 6] 则最大胜数为 7,但我的算法给出 5。

这里有我遗漏的东西吗?

@chqrlie 建议的修订解决方案

def optimal_reorder2(A,B):
    arrA = A.copy()
    C = [None] * len(B)
    for i in range(len(B)):
        k = i + 1
        all_ele = []
        while (k < len(arrA)):
            if arrA[k] > B[i]:
                all_ele.append(arrA[k])
            k += 1
        if all_ele:
            e = min(all_ele)
        else:
            e = min(arrA)
        C[i] = e
        arrA.remove(e)
    return C

【问题讨论】:

    标签: arrays python-3.x sorting mergesort array-algorithms


    【解决方案1】:

    这个算法怎么样:

    • 从一个空数组C开始。
    • 对于range(len(B)) 中的每个索引i
      • 如果A的其余元素至少有一个大于B[i],则选择e作为这些元素中的最小元素,否则选择e作为A的最小元素。
      • 设置C[i] = e 并从A 中删除e

    C 应该是对A 的重新排序,以最大限度地增加真正的比较次数C[i] &gt; B[i]

    【讨论】:

    • 实现了您的算法,现在似乎可以为上面指定的测试用例以及stackoverflow.com/questions/35806804/… 提供正确的答案。但是想知道这是否是解决极端测试用例的通用解决方案,其中两个数组都允许重复
    • 我根据您的建议用修改后的解决方案编辑了问题@chqrlie
    • @VikasChitturi:我没有找到正式的证据证明该算法在所有情况下都能找到好的解决方案,也没有找到反例。似乎重复的条目不应该有所作为,但我无法再次证明这一点。
    【解决方案2】:

    可能有比这更好的算法,但您可以将其视为最大二分匹配问题。将数组视为二分图中的两组节点,然后如果 A[i] > B[j],则添加从 A[i] 到 B[j] 的边。然后,任何匹配都会告诉您如何将 A 的元素与 B 的元素配对,以使 A 元素“胜出” B 元素,而最大匹配会告诉您如何做到这一点以最大化获胜次数。

    我确信有更好的方法来做到这一点,我很高兴看到其他人想出什么。但这至少表明你可以在多项式时间内解决这个问题。

    【讨论】:

    • 深思!谢谢。另一种解决方案是天真地采用数组 A 的每个排列,进行比较并计算获胜次数,最后取所有获胜次数的最大值。(我只是使用 python 的 itertools 对其进行编码,但它类似于指数时间复杂度)跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 2012-06-04
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多