列表中的最小交换元素使其与另一个列表相同并计算python中的交换

Posted

技术标签:

【中文标题】列表中的最小交换元素使其与另一个列表相同并计算python中的交换【英文标题】:Minimum swaping elements in a list to make it same like another list and count the swap in python 【发布时间】:2020-06-18 00:46:47 【问题描述】:

我必须列出我的输入, a = [0,1,0,1] 和 b = [1,0,1,0]

注意:两个列表的元素都只有 0 和 1。如果不能通过交换使它们都相同,那么我将打印 -1。如果开始时相同,我将打印 0,如果不相同则, 我想做 a == b,在这种情况下,我需要最少 2 次交换。 第一个交换将是 a 的第 0 个索引和 a 的第一个索引和 第二次交换将是 a 的第二个索引和 a 的第三个索引。 之后 a 将与 b 相同。

这是我的代码:

def xx(a,b):
    move = 0
    if a == b:
        print(0)
    else:
        if len(a) == 1 and len(a) == len(b):
            print(-1)
        else:
            for i in range(len(a)):
                if a[i] != b[i]:
                    j = a.index(b[i])
                    a[i] = a[j]
                    move += 1
            count_swap = move // 2
            print(count_swap)
a = list(map(int,input().split()))
b = list(map(int,input().split()))
xx(a,b)

是否有任何有效的方法来获取交换计数?

输入:

0 1 0 1
1 0 1 0

输出:

2

输入:

0 1 0
1 0 0

输出:

1

输入:

0
1

输出:

-1

【问题讨论】:

【参考方案1】:

首先,为了使交换使列表相等,它们必须以相同数量的 1 和 0 开头。所以我们可以使用Counter 来检查是否不可能。

其次,一次交换必然会解决两个差异。所以我们可以只计算差异并除以 2。我们实际上不必执行任何交换。

演示:

from collections import Counter

def swap_count(xs, ys):
    if xs == ys:
        return 0
    else:
        cx = Counter(xs)
        cy = Counter(ys)
        if cx == cy:
            n_diffs = sum(x != y for x, y in zip(xs, ys))
            return n_diffs // 2
        else:
            return -1

def main():
    tests = [
        (2, [0, 1, 0, 1], [1, 0, 1, 0]),
        (1, [0, 1, 0], [1, 0, 0]),
        (-1, [0], [1]),
        (0, [0, 1, 0, 1], [0, 1, 0, 1]),
    ]
    for exp, xs, ys in tests:
        n = swap_count(xs, ys)
        print(n == exp, n, xs, ys)

main()

输出:

True 2 [0, 1, 0, 1] [1, 0, 1, 0]
True 1 [0, 1, 0] [1, 0, 0]
True -1 [0] [1]
True 0 [0, 1, 0, 1] [0, 1, 0, 1]

【讨论】:

【参考方案2】:

这应该是一个 O(N) 解决方案,它迭代项目并在列表 b 上执行交换。如果我们离开列表 b (IndexError) 的末尾,则无法找到解决方案并返回 -1。

def count_swaps(a, b):
    swaps = 0
    for idx in range(len(a)):
        if a[idx] != b[idx]:
            try:
                b[idx], b[idx + 1] = b[idx + 1], b[idx]
                swaps += 1
            except IndexError:
                return -1

    return swaps


assert count_swaps([0, 1, 0, 1], [1, 0, 1, 0]) == 2
assert count_swaps([0, 1, 0], [1, 0, 0]) == 1
assert count_swaps([0], [1]) == -1

【讨论】:

以上是关于列表中的最小交换元素使其与另一个列表相同并计算python中的交换的主要内容,如果未能解决你的问题,请参考以下文章

将保存在数据库 sqlite 中的列表视图中的一行发送到另一个列表视图,并使其与第一个列表视图中的行相同

如何重新采样 DataFrame 以使其与另一个 DataFrame 正确对齐?

Hibernate 不包含与另一个实体列表中的实体相同类型的子实体

确保三个列表具有相同数量元素的程序

查找列表中的最小元素(递归) - Python

选择排序