我正在学习Codility Counting Lesson(https://codility.com/media/train/2-CountingElements.pdf),我需要帮助才能理解最快的解决方案。
我想知道为什么差异在第8行d //= 2
除以2?难道不足以找到我们可以在数组之间交换的元素吗?
问题:
您将获得一个整数
m
(1 < m < 1000000
)和两个非空, 零索引数组A
和B
n
个整数,a0
,a1
,..., 分别为an−1
和b0
,b1
,...,bn−1
(0 < ai
,bi < m
)。 目标是检查是否存在可以进行的交换操作 以这样的方式对这些数组执行,即元素的总和 数组A
等于交换后数组B
中元素的总和。通过 交换操作我们的意思是从数组A
和一个中选择一个元素 数组B
中的元素并进行交换。
解决方案:
def fast_solution(A, B, m):
n = len(A)
sum_a = sum(A)
sum_b = sum(B)
d = sum_b - sum_a
if d % 2 == 1:
return False
d //= 2
count = counting(A, m)
for i in xrange(n):
if 0 <= B[i] - d and B[i] - d <= m and count[B[i] - d] > 0:
return True
return False
答案 0 :(得分:8)
A[i
]和B[j]
之间的互换将B[j]-A[i]
添加到sum(A)
,从sum(B)
中减去相同的值;因此它会影响总和的差异两次 B[j]-A[i]
。
因此,将原始差异减半是正确的(在检查它之后 - 如果奇怪的是没有交换将起作用! - )以形成可能的目标交换。
另请注意,他们提供的counting
函数不是最佳的现代Python - 为了避免重新发明&#34;计算项目的特定轮次,请参阅https://docs.python.org/2/library/collections.html#collections.Counter获取Python 2,或者Python 3的https://docs.python.org/3/library/collections.html#collections.Counter。
答案 1 :(得分:3)
让Ea = a0 + a1 + .. + a(n-1)
。让Eb = b0 + b1 + .. + b(n-1)
。然后,交换元素ai
和bj
会对这些总结产生以下影响:Ea - ai + bj
,Eb + ai - bj
。根据问题描述,那些总和应该相等,所以Ea - ai + bj = Eb + ai - bj
让我们指定d = bj - ai
。然后我们有以下相等性:Ea + d = Eb - d
,它给我们2d = Eb - Ea
或d = (Eb - Ea)/2
。对于(Eb - Ea)奇数的情况,请参阅Alex Martelli的comment
唯一剩下的就是找到bj
和ai
这样的bj - ai = d
。