栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

哪种是计算nCr的更好方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

哪种是计算nCr的更好方法

两种方法都可以节省时间,但是第一种非常容易发生整数溢出。

方法1:

这种方法将在最短的时间内(最多在

n/2
多次迭代中)生成结果,并且通过仔细地进行乘法运算可以减少溢出的可能性:

long long C(int n, int r) {    if(r > n - r) r = n - r; // because C(n, r) == C(n, n - r)    long long ans = 1;    int i;    for(i = 1; i <= r; i++) {        ans *= n - r + i;        ans /= i;    }    return ans;}

该代码将从较小的一端开始分子的乘法,并且由于任何

k
连续整数的乘积
k!
都可被整除,因此不会存在除数问题。但溢出的可能性仍然存在,另一个有用的技巧,可以划分
n- r + i
i
通过做乘法和除法(和之前的GCD 可能发生溢出)。

方法二:

通过这种方法,您实际上将建立Pascal的Triangle。动态方法比递归方法快得多(第一种是递归的,

O(n^2)
而另一种是指数的)。但是,您还需要使用
O(n^2)
内存。

# define MAX 100 // assuming we need first 100 rowslong long triangle[MAX + 1][MAX + 1];void makeTriangle() {    int i, j;    // initialize the first row    triangle[0][0] = 1; // C(0, 0) = 1    for(i = 1; i < MAX; i++) {        triangle[i][0] = 1; // C(i, 0) = 1        for(j = 1; j <= i; j++) { triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j];        }    }}long long C(int n, int r) {    return triangle[n][r];}

然后,你可以在任何查找

C(n, r)
O(1)
时间。

如果您需要一个特定的

C(n,r)
(即不需要整个三角形),则可以
O(n)
通过覆盖三角形的同一行(从上到下)来消耗内存。

# define MAX 100long long row[MAX + 1];int C(int n, int r) {    int i, j;    // initialize by the first row    row[0] = 1; // this is the value of C(0, 0)    for(i = 1; i <= n; i++) {        for(j = i; j > 0; j--) {  // from the recurrence C(n, r) = C(n - 1, r - 1) + C(n - 1, r)  row[j] += row[j - 1];        }    }    return row[r];}

内循环从头开始,以简化计算。如果从索引0开始,则需要另一个变量来存储要覆盖的值。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/437221.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号