有没有办法在O(1)中找到组合数(不是实际组合)?我在这里读到了答案 - time and space complexity of finding combination (nCr)。答案说,需要O(n!)来找到实际的组合,但只需要O(1)来找到这种组合的数量。我无法理解它是如何完成的。请解释我如何在O(1)中做到这一点。这里,O(1)是时间复杂度。
[编辑]:我遇到的主要问题是如何实现n!在O(1)。
答案 0 :(得分:3)
请检查以下C
计划。它需要n
和r
作为输入并计算 n C r 值:
int main(){
int n, r;
scanf("%d", &n);
scanf("%d", &r);
/*
* nCr = n! / !(n-r) / !(r)
* = n * n-1 * n-2 * .... * 1 / (n-r * n-r-1 * .. * 1) /
* (r * r-1 * ... * 1)
* = n * n-1 * n-2 * n-r+1 / (r * r-1 * ... * 1)
*
*/
int result = 1;
int i;
for (i=0; i<r; i++){
result *= (n-i); // n * n-1 * n-2 * .... * n-(r-1)
result /= (i+1); // r * r-1 * ... * 1
}
/* The loop is going to run only r times for any n
* Time to calculate nCr : O(r)
* Space complexity: O(1)
*/
printf("Result of C(%d, %d) = %d", n, r, result);
return 0;
}
要计算它,循环仅适用于&#39; r&#39;时间。
因此,计算nCr值的时间复杂度为O(r)
但空间复杂度为O(1)
我猜你一定是对这两个复杂性命令感到困惑。希望,它会帮助你。
答案 1 :(得分:1)
如果你试图在恒定时间内计算ggmap(dub_map,
base_layer = ggplot(data=df, aes(x = Longitude,
y = Latitude,
label=Station.Area))) +
geom_point(fill = "green", alpha =0.8, size = 5, shape = 21) +
geom_text()
,为什么不使用斯特林的近似值?
n!
或n! \approx sqrt(2 * pi * n) * (n / e)^n
:
C
我认为这将使您最接近恒定时间,每个操作的实际运行时间取决于架构。
来源:
https://en.wikipedia.org/wiki/Stirling%27s_approximation
https://github.com/ankurp/C-Algorithms/blob/master/factorial/fact.c
答案 2 :(得分:0)
如果您使用的计算平台计算n,nCr的运行时复杂性只能在O(1)中!在O(1)。在标准计算机上,情况并非如此。
但我们可以使用exp(n)和log(n)通常为an O(1) operation for IEEE doubles和implement an approximation of log(n!)的事实 - 基于斯特林的近似 - 在O(1)中:
logf(n) = log(n!) = (n – 0.5) * log(n) – n + 0.5 * log(2 * PI) + 1/(12 * n)
如果我们将这个与log(n!)的查找表结合起来,对于n≤255,我们仍然会有至少14个有效数字,我们可以计算出非常好的nCr近似值,如下所示:
binomial(n, r) = exp(logf(n) - logf(n - r) - logf(r))
答案 3 :(得分:0)
Ajeet's answer应该被接受,但是我认为可以将其改进为Min(O(r),O(n-r))
,如果减少的话,它仍然是O(r)
。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System. in );
int n = sc.nextInt();
int r = sc.nextInt();
// choose smaller one
if (n - r < r) {
r = n - r;
System.out.printf("Change %d to %d\n", n - r, r);
}
/*
* nCr = n! / ((n-r)! * (r)! )
* = (n * n-1 * n-2 * .... * 1) / ( (n-r * n-r-1 * .. * 1) * (r * r-1 * ... * 1) )
* = (n * n-1 * n-2 * n-r+1) / (r * r-1 * ... * 1)
*/
int result = 1;
for (int i = 0; i < r; i++) {
result *= (n - i); // n * n-1 * n-2 * .... * n-(r-1)
result /= (i + 1); // r * r-1 * ... * 1
}
/*
* The loop is going to run only r times or (n-r) times for any n Time to calculate nCr : Min ( O(r) , O(n-r) )
* Space complexity: O(1)
*/
System.out.printf("Result of C(%d, %d) = %d", n, r, result);
}
}
答案 4 :(得分:0)
在某些用例中,最好通过生成帕斯卡三角形来预先计算 O(n^2) 中的所有答案,以便查询为 O(1)。
其他时候你只需要计算 n!一个一个,所以复杂度是 O(n)。
答案 5 :(得分:-4)
有没有办法在O(1)
中找到组合数(而不是实际组合)
是的,您可以使用公式2 n -1找到数字n
的组合数量而不重复,不包括空集。