📅  最后修改于: 2023-12-03 14:55:50.440000             🧑  作者: Mango
给定一个数组arr,一个整数K和一个整数N。检查是否存在一种排列,使得对于范围[0,N-1]中的每个i值,(arr[i]+i*K)%N等于i。
对于一个数组arr和一个整数K,对于范围[0,N-1]中的每个i,等式(arr[i]+iK)%N=i至少需要满足一个条件:arr[i]%N=iK%N。所以,我们可以计算出该条件下数组中每个元素的出现次数,并检查它们是否相同。
def can_rearrange_array(arr, K, N):
counts = [0] * N
for i in range(N):
counts[arr[i] % N] += 1
for i in range(N):
if counts[i] != counts[(i*K)%N]:
return False
return True
让我们从简单的情况开始考虑。当K = 1时,等式可以被改写为arr[i] = i(N-1)。因此,如果arr已经包含所有整数i(N-1),则等式必定成立。
如果K!=1,我们可以将arr中的元素分组并在不改变等式的情况下重新排列。我们把arr[i]简写为x[i]。然后可以将等式改写为(x[i] + iK) = iN + j(i)。通过对equation进行变换,我们得到
$$ \frac{x[i]+i*K}{N} = i + \frac{j[i]}{N} $$
因此,所有的x[i]+i*K都必须是N的倍数。
def can_rearrange_array(arr, K, N):
gcd = math.gcd(K, N)
counts = collections.Counter([x % gcd for x in arr])
for i in range(gcd):
j = i
while j < N and counts[i] == counts[j % gcd]:
j += gcd
if j >= N:
return True
return False
arr1 = [1, 2, 3, 4, 5, 6, 7, 8]
K1 = 3
N1 = 8
arr2 = [1, 2, 3, 4, 5, 6, 7, 8]
K2 = 4
N2 = 8
arr3 = [0, 1, 2, 3, 4, 5, 6, 7]
K3 = 1
N3 = 8
print(can_rearrange_array(arr1, K1, N1)) # True
print(can_rearrange_array(arr2, K2, N2)) # False
print(can_rearrange_array(arr3, K3, N3)) # True
输出:
True
False
True