python:在两个数组之间交换元素的算法
我正在分析Codibility提出的python中的计数 我不理解这个算法的最后一个循环(最后5行)中使用的逻辑。python:在两个数组之间交换元素的算法,python,Python,我正在分析Codibility提出的python中的计数 我不理解这个算法的最后一个循环(最后5行)中使用的逻辑。 有人能帮忙吗 问题是: 给您一个整数m(1
有人能帮忙吗 问题是: 给您一个整数
m
(1
)和两个非空,
零索引数组A
和B
的n
整数,a0
,a1
,
an−1
和b0
,b1
<代码>bn−分别为1(0
,bi
)。
目的是检查是否存在可以执行的交换操作
在这些数组上执行,以使
数组A
等于交换后数组B
中元素的总和。通过
交换操作我们的意思是从数组A
中选择一个元素,然后选择一个
数组B
中的元素并交换它们
解决方案:
def counting(A, m):
n = len(A)
count = [0] * (m + 1)
for k in xrange(n):
count[A[k]] += 1
return count
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
def计数(A,m):
n=len(A)
计数=[0]*(m+1)
对于X范围内的k(n):
计数[A[k]+=1
返回计数
def fast_解决方案(A、B、m):
n=len(A)
总和a=总和(a)
sum_b=sum(b)
d=总和b-总和a
如果d%2==1:
返回错误
d/=2
计数=计数(A,m)
对于x范围内的i(n):
如果0我不确定我是否正确理解了你的想法。以下是我的理解:
def counting(A, m):
n = len(A)
count = [0] * (m + 1)
for k in xrange(n):
count[A[k]] += 1
return count # this essentially build a counter
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) # get the dict
for i in xrange(n):
if 0 <= B[i] - d and B[i] - d <= m and count[B[i] - d] > 0:
# the first two conditions are to verify that B[i]-d exists as a key (index) in counter.
# then check if there actually exists the value.
# if count > 0, then you can swap the two to get same sum
return True
return False
但是在任何情况下,这段代码只需检查解决方案是否存在,只需进行一次交换,确保检查这是否是您想要的 我建议您再次阅读练习中给出的解释。它已经解释了算法的工作原理。但是,如果您仍然有问题,请拿一张纸和一些非常简单的示例数组,一步一步地介绍解决方案
例如,让A=[6,6,1,2,3]
和B=[1,5,3,2,1]
现在让我们看一下算法
我假设您了解此方法的工作原理:
def counting(A, m):
n = len(A)
count = [0] * (m + 1)
for k in xrange(n):
count[A[k]] += 1
return count
它只返回一个包含计数的列表,如练习中所述。对于列表A和m=10,它将返回:
[0, 1, 1, 1, 0, 0, 2, 0, 0, 0, 0]
然后我们通过主方法fast\u解决方案(A,B,m)
:
n=11
(这将在循环中使用)
A的和等于18
,B的和等于12
差异d
是-6
(sum_b-sum_a),它是偶数。请注意,如果差值为奇数,则没有可用的交换,结果为假
然后将d
除以2
。它变为-3
对于A,我们得到count[0,1,1,1,0,0,2,0,0,0]
(如前所述)
然后,我们只需使用xrange
迭代列表B并检查条件(循环从0到11,但不包括11)。让我们一步一步地检查一下:
i=0
,B[0]-(-3)
是1+3=4
。4大于或等于0,小于或等于10(请记住,我们选择了m
作为10
)。但是,count[4]
为0且不大于0(注意列表count
从索引0
开始)。如果条件不满足,我们就更进一步
i=1
,B[1]-(-3)
是5+3=8
。8大于或等于0且小于或等于10。但是,count[8]
为0,条件失败
i=2
,B[2]-(-3)
是3+3=6
。6大于0且小于10。此外,计数[6]
为2且大于0。所以我们找到了号码。循环停止,返回True。这意味着B中有这样一个数字可以与a中的一个数字交换,因此a的和等于B的和。事实上,如果我们将a中的6与B中的3交换,那么它们的和等于15
希望这有帮助。好的,我明白了。知道数组B和A之间的差异后,我们检查B的每个元素是否可以替换为差/2以下的数字(我们称之为x),这样数组的和就相等了。循环的第一部分检查x是否在感兴趣的范围内(0到m之间),第二部分检查x是否存在于A中,如果存在(计数>0),则交换是可能的。
[0, 1, 1, 1, 0, 0, 2, 0, 0, 0, 0]