此代码计算有多少整数三元组总和为0:完整代码为here。
initialise an int array of length n
int cnt = 0 // cnt is the number of triples that sum to 0
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
for (int k = j+1; k < n; k++) {
if (array[i]+array[j]+array[k] == 0) {
cnt++;
}
}
}
}
现在,根据罗伯特·塞奇威克的书“算法”,我读到了:
cnt
到0
的初始化只执行一次。cnt++
从0执行到找到三元组的次数。n(n-1)(n-2)/6
次。我做了一些实验,所有这些都是真的。但我完全不知道他们如何计算if语句执行的次数。 我不确定,但我认为:
n
表示来自i to n
(n-1)
表示从i+1
到n
(n-2)
表示从j+1
到n
/6
我不知道这是为了什么。任何人都可以解释如何计算这个吗?
答案 0 :(得分:3)
它的总和。
n-j-1
次n-i-1
次n
次。 Sum all of these您获得调用cnt++
的总次数。
请注意,每次执行中间循环的次数不是n-1
,而是n-i-1
,其中i
是外循环的索引。同样适用于中间循环。
/6
因素来自于求和公式中的考虑因素。
答案 1 :(得分:3)
这可以被视为combinatorial问题。要从n
项目中选择3个唯一项目(链接文章中为k=3
),可以提供n!/(n-3)! = n*(n-1)*(n-2)
种可能性。但是,在代码中,3个项目的顺序并不重要。对于3个项目的每个组合,有3! = 6
个排列。所以我们需要除以6才能获得无序的可能性。我们得到n!/(3!(n-3)!) = n(n-1)(n-2)/6
答案 2 :(得分:3)
第一个循环执行N次(0到N-1)
执行外循环的时间是:
Fi(0) + Fi(1) + Fi(2)...Fi(N-1)
当i
为0
时,中间循环执行N-1
次(1到N-1)
当i
为1
时,中间循环执行N-2
次(2到N-1)
...
执行中间循环的时间是:
Fi(0) = Fj(1) + Fj(2) ... Fj(N-1)
Fi(1) = Fj(2) + Fj(3) ... Fj(N-1)
Fi(0) + Fi(1) + Fi(2)...Fi(N-1) = Fj(1) + 2Fj(2) + ... (N-1)Fj(N-1)
现在来到最里面的循环:
当j
为1
时,内循环执行N-2
次(2到N-2)
当j
为2
时,内循环执行N-3
次(3到N-2)
...
Fj(1) = Fk(2) + Fk(3) ... Fk(N-1) = 2 + 3 + ... N-1
Fj(2) = Fk(3) + Fk(4) ... Fk(N-1) = 3 + 4 + ... N-1
Fj(1) + 2Fj(2) + ... (N-1)Fj(N-1) = (2 + 3 + ... N-1) + (3 + 4 + ... N-1) ... (N-1)
= 1 x 2 + 2 x 3 + 3 x 4 .... (N-2) x (N-1)
= 1x1 + 2x2 + 3x3 + 4x4 .... (N-1)*(N-1) - (1 + 2 + 3 + 4 + N-1)
= (N-1) N (N+1) / 6 - N (N-1) / 2
= N (N-1) ((N+1)/2 - 1/2)
= N (N-1) (N-2) / 6
您可能还需要检查:公式,以计算first N natural numbers的平方和first N natural numbers的总和。
替代解释:
您正在寻找所有三胞胎对。这可以用 N C 3 方式完成。即(N) * (N-1) * (N-2) / (1 * 2 * 3)
种方式。
答案 3 :(得分:1)
该公式的基础来自进展的总和:
1+2 = 3
1+2+3 = 6
1+2+3+4 = 10
存在公式:
Sum(1..N) == N*(N+1)/2
1+2+3+4 = 4*5/2 = 10
通过递归进展(就像在这种情况下),您可以得到另一个总和公式。
答案 4 :(得分:0)
在你的代码中,我从0运行到n,j从i到n,k从j到n,if语句执行大约n ^ 3/6次。要了解为什么会这样,请查看此代码,这些代码显然会经常执行if语句:
int cnt = 0 // cnt is the number of triples that sum to 0
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
if (j > i && k > j) {
if (array[i]+array[j]+array[k] == 0) {
cnt++;
}
}
}
}
}
内循环现在显然执行n ^ 3次。如果i