📅  最后修改于: 2023-12-03 15:06:14.004000             🧑  作者: Mango
本文介绍的问题是如何计算两个1到N值的数组之间所有不同对的和。
给定两个长度均为N的整数数组A和B,计算所有不同对(i, j)满足i∈[1,N], j∈[1,N]且Ai ≠ Bj的Ai和Bj的和的和。
我们可以考虑把问题拆解成3个子问题:1)计算所有相同下标的数的和;2)计算所有不同下标并且Ai ≠ Bj的数的和;3)计算所有不同下标并且Ai = Bj的数的和。最终的结果就是三个子问题的和。
这很简单,我们可以遍历数组A和数组B,如果下标相同,那么就把它们的和加到结果里面即可。
result = 0
for i in range(N):
result += A[i] + B[i] if A[i] == B[i] else 0
我们可以使用两个for循环,枚举所有的不同下标并且若Ai ≠ Bj,就将它们的和加到结果里面。
for i in range(N):
for j in range(N):
if i != j and A[i] != B[j]:
result += A[i] + B[j]
可以使用一个计数器来解决,它用于记录相同的数的数量。然后将所有相同数的和乘以计数器即可。
count = 0
same_sum = 0
for i in range(N):
if A[i] == B[i]:
count += 1
same_sum += A[i]
result += same_sum * count
时间复杂度为O(N^2),不过可以通过优化第二个子问题的算法,将时间复杂度降为O(N)。
count = [0]*(2*N)
same_sum = 0
for i in range(N):
count[A[i]] += 1
count[B[i]+N] += 1
if A[i] == B[i]:
same_sum += A[i]
for c in count:
if c > 1:
result += (c*(c-1)//2) * (N-same_count) * 2
result += same_sum * (N*(N-1)//2 - result//2)
计算数组之间不同对的和问题,可以使用拆分成3个子问题来解决,并将它们的结果相加。这个问题的时间复杂度为O(N^2),但是可以通过一些技巧将它降至O(N)。