在O(n)中排序两个数组(时间和空间)

时间:2018-06-13 15:50:21

标签: algorithm data-structures computer-science

  

给定两个(可能是未排序的)数组AB以及交换元素swap(A, B, i)A[i]的操作B[i],您需要返回交换的最小数量,因此两个数组严格增加(或-1,如果不可能)

我用贪婪的解决方案来得很快(如果你愿意,我可以附上代码),但显然在某些情况下(我不知道)它没有产生正确的答案。

为什么贪婪的方法不够好? 什么是达到最小交换数量的替代方法?

修改
这是我的代码

def solution(A, B):
    n = len(A)
    swaps = 0
    for i in range(1, n):

        if A[i] > A[i - 1] and B[i] > B[i - 1]:
            continue

        if A[i] < A[i - 1] and B[i] < B[i - 1]:
            return -1
        elif A[i] < A[i - 1]:
            if B[i - 1] < A[i]:
                A[i], B[i] = B[i], A[i]
                swaps += 1
            else:
                return -1
        else:
            # B[i] < B[i - 1]
            if A[i - 1] < B[i]:
                A[i], B[i] = B[i], A[i]
                swaps += 1
            else:
                return -1


    return swaps

# test
assert(solution([5, 3, 7, 7, 10], [1, 6, 6, 9, 9]))

1 个答案:

答案 0 :(得分:2)

您可以使用DP实现此目的:

一种方法可以是: 对于每对A [i]和B [i],我们可以选择是否交换。所以我们定义了两个dp数组,keep [i]意味着如果我们不交换A [i]和B [i],那么交换的最小数量是多少。如果我们交换A [i]和B [i],交换[i]是交换的最小数量。

  • A [i]&gt; A [i -1]&amp;&amp; B [i]&gt; B [i - 1], 如果我们选择保留,我们应该保留以前的i - 1元素。所以保持[i] =保持[i - 1] 如果我们选择交换,为了维持排序顺序,我们必须交换先前的第i - 1个元素。所以交换[i] = swap [i - 1] + 1;

  • A [i]&gt; B [i - 1]&amp;&amp; B [i]&gt; A [i - 1] 如果我们选择保留,请保持[i] = Math.min(保持[i],交换[i - 1]) 如果我们选择交换,交换[i] = Math.min(交换[i],保持[i - 1] + 1)

  • 对于诸如A [i]&lt; B [i - 1],返回-1

时间复杂度:O(n)