今天打卡的章节是《算法零基础100讲》(第4讲) 组合数
附上链接:https://blog.csdn.net/WhereIsHeroFrom/article/details/120875081
目录
主要内容
1、组合数的定义
从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。
2、组合数的定义
1、互补性质
组合数性质如上图所示:
即从m个不同元素中取出n个元素的组合数=从m个不同元素中取出(m-n)个元素的组合数
这个性质很容易理解,例如C(9,2)=C(9,7),即从9个元素里选择2个元素的方法与从9个元素里选择7个元素的方法是相等的。
规定:C(m,0)=1
2、组合恒等式
若表示在n个物品中选取m个物品,则如存在下述公式: C(n,m)= C(n,n-m)= C(n-1,m-1)+C(n-1,m)
3、组合数的求法
方法一:通过定义式直接计算
long long C(long long n,long long m){
long long ans = 1;
for(long long i = 1;i <= n;++i){
ans *= i;
}
for(long long i = 1;i <= m;++i){
ans /= i;
}
for(long long i = 1;i <= n - m;++i){
ans /= i;
}
return ans;
}
方法二:通过递推公式计算
long long C(long long n,long long m){
if(m == 0 || m == n){
retunr 1;
}else{
return C(n-1,m) + C(n-1,m-1);
}
}
方法三:通过定义式的变形来计算
long long C(long long n,long long m){
long long ans = 1;
for(long long i = 1;i <= m;i++){
ans = ans * (n - m + i) / i; //注意:一定要先乘再除!!!
}
return ans;
}
力扣习题
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** generate(int numRows, int* returnSize, int** returnColumnSizes){
int **ans=(int **)malloc(sizeof(int *)*numRows);
*returnColumnSizes=(int *)malloc(sizeof(int)*numRows);
*returnSize=numRows;
for(int i=0;i<numRows;i++)
{
ans[i]=(int *)malloc(sizeof(int)*(i+1));
(*returnColumnSizes)[i]=i+1;
for(int j=0;j<=i;j++)
{
if(j==0||j==i)
{
ans[i][j]=1;
}
else
{
ans[i][j]=ans[i-1][j]+ans[i-1][j-1];
}
}
}
return ans;
}
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* getRow(int rowIndex, int* returnSize){
*returnSize=rowIndex+1;
int *ans=(int *)malloc(sizeof(int)*(rowIndex+1));
memset(ans,0,sizeof(int)*(rowIndex+1));
ans[0]=1;
for(int i=1;i<=rowIndex;i++)
{
for(int j=i;j>0;j--)
{
ans[j]=ans[j]+ans[j-1];
}
}
return ans;
}