python:在两个数组之间交换元素的算法

python:在两个数组之间交换元素的算法,python,Python,我正在分析Codibility提出的python中的计数 我不理解这个算法的最后一个循环(最后5行)中使用的逻辑。 有人能帮忙吗 问题是: 给您一个整数m(1

我正在分析Codibility提出的python中的计数

我不理解这个算法的最后一个循环(最后5行)中使用的逻辑。
有人能帮忙吗

问题是:

给您一个整数
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]