The following are the common definitions of Binomial Coefficients.
A binomial coefficient C(n, k) can be defined as the coefficient of x^k in the expansion of (1 + x)^n.
A binomial coefficient C(n, k) also gives the number of ways, disregarding order, that k objects can be chosen from among n objects more formally, the number of k-element subsets (or k-combinations) of a n-element set.
The Problem
Write a function that takes two parameters n and k and returns the value of Binomial Coefficient C(n, k). For example, your function should return 6 for n = 4 and k = 2, and it should return 10 for n = 5 and k = 2.
1) Optimal Substructure
The value of C(n, k) can be recursively calculated using the following standard formula for Binomial Coefficients.
C(n, k) = C(n-1, k-1) + C(n-1, k)
C(n, 0) = C(n, n) = 1
Following is a simple recursive implementation that simply follows the recursive structure mentioned above.
C++
#include <bits/stdc++.h>
using namespace std;
int binomialCoeff( int n, int k)
{
if (k > n)
return 0;
if (k == 0 || k == n)
return 1;
return binomialCoeff(n - 1, k - 1)
+ binomialCoeff(n - 1, k);
}
int main()
{
int n = 5, k = 2;
cout << "Value of C(" << n << ", " << k << ") is "
<< binomialCoeff(n, k);
return 0;
}
|
C
#include <stdio.h>
int binomialCoeff( int n, int k)
{
if (k > n)
return 0;
if (k == 0 || k == n)
return 1;
return binomialCoeff(n - 1, k - 1)
+ binomialCoeff(n - 1, k);
}
int main()
{
int n = 5, k = 2;
printf ( "Value of C(%d, %d) is %d " , n, k,
binomialCoeff(n, k));
return 0;
}
|
Java
import java.util.*;
class GFG {
static int binomialCoeff( int n, int k)
{
if (k > n)
return 0 ;
if (k == 0 || k == n)
return 1 ;
return binomialCoeff(n - 1 , k - 1 )
+ binomialCoeff(n - 1 , k);
}
public static void main(String[] args)
{
int n = 5 , k = 2 ;
System.out.printf( "Value of C(%d, %d) is %d " , n, k,
binomialCoeff(n, k));
}
}
|
Python3
def binomialCoeff(n, k):
if k > n:
return 0
if k = = 0 or k = = n:
return 1
return binomialCoeff(n - 1 , k - 1 ) + binomialCoeff(n - 1 , k)
n = 5
k = 2
print ( "Value of C(%d,%d) is (%d)" % (n, k,
binomialCoeff(n, k)))
|
C#
using System;
class GFG {
static int binomialCoeff( int n, int k)
{
if (k > n)
return 0;
if (k == 0 || k == n)
return 1;
return binomialCoeff(n - 1, k - 1)
+ binomialCoeff(n - 1, k);
}
public static void Main()
{
int n = 5, k = 2;
Console.Write( "Value of C(" + n + "," + k + ") is "
+ binomialCoeff(n, k));
}
}
|
Javascript
<script>
function binomialCoeff(n , k)
{
if (k > n)
return 0;
if (k == 0 || k == n)
return 1;
return binomialCoeff(n - 1, k - 1)
+ binomialCoeff(n - 1, k);
}
var n = 5, k = 2;
document.write( "Value of C(" +n+ ", " +k+ ") is " +binomialCoeff(n, k));
</script>
|
PHP
<?php
function binomialCoeff( $n , $k )
{
if ( $k > $n )
return 0;
if ( $k ==0 || $k == $n )
return 1;
return binomialCoeff( $n - 1, $k - 1) +
binomialCoeff( $n - 1, $k );
}
$n = 5;
$k = 2;
echo "Value of C" , "(" , $n , $k , ") is "
, binomialCoeff( $n , $k );
?>
|
Output
Value of C(5, 2) is 10
Time Complexity: O(n*max(k,n-k))
Auxiliary Space: O(n*max(k,n-k))
2) Overlapping Subproblems
It should be noted that the above function computes the same subproblems again and again. See the following recursion tree for n = 5 and k = 2. The function C(3, 1) is called two times. For large values of n, there will be many common subproblems.

Binomial Coefficients Recursion tree for C(5,2)
Since the same subproblems are called again, this problem has the Overlapping Subproblems property. So the Binomial Coefficient problem has both properties (see this and this) of a dynamic programming problem. Like other typical Dynamic Programming(DP) problems, re-computations of the same subproblems can be avoided by constructing a temporary 2D-array C[][] in a bottom-up manner. Following is Dynamic Programming-based implementation.
C++
#include <bits/stdc++.h>
using namespace std;
int min( int a, int b);
int binomialCoeff( int n, int k)
{
int C[n + 1][k + 1];
int i, j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= min(i, k); j++) {
if (j == 0 || j == i)
C[i][j] = 1;
else
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
}
return C[n][k];
}
int min( int a, int b) { return (a < b) ? a : b; }
int main()
{
int n = 5, k = 2;
cout << "Value of C[" << n << "][" << k << "] is "
<< binomialCoeff(n, k);
}
|
C
#include <stdio.h>
int min( int a, int b);
int binomialCoeff( int n, int k)
{
int C[n + 1][k + 1];
int i, j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= min(i, k); j++) {
if (j == 0 || j == i)
C[i][j] = 1;
else
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
}
return C[n][k];
}
int min( int a, int b) { return (a < b) ? a : b; }
int main()
{
int n = 5, k = 2;
printf ( "Value of C(%d, %d) is %d " , n, k,
binomialCoeff(n, k));
return 0;
}
|
Java
class BinomialCoefficient {
static int binomialCoeff( int n, int k)
{
int C[][] = new int [n + 1 ][k + 1 ];
int i, j;
for (i = 0 ; i <= n; i++) {
for (j = 0 ; j <= min(i, k); j++) {
if (j == 0 || j == i)
C[i][j] = 1 ;
else
C[i][j] = C[i - 1 ][j - 1 ] + C[i - 1 ][j];
}
}
return C[n][k];
}
static int min( int a, int b) { return (a < b) ? a : b; }
public static void main(String args[])
{
int n = 5 , k = 2 ;
System.out.println( "Value of C(" + n + "," + k
+ ") is " + binomialCoeff(n, k));
}
}
|
Python3
def binomialCoef(n, k):
C = [[ 0 for x in range (k + 1 )] for x in range (n + 1 )]
for i in range (n + 1 ):
for j in range ( min (i, k) + 1 ):
if j = = 0 or j = = i:
C[i][j] = 1
else :
C[i][j] = C[i - 1 ][j - 1 ] + C[i - 1 ][j]
return C[n][k]
n = 5
k = 2
print ( "Value of C[" + str (n) + "][" + str (k) + "] is "
+ str (binomialCoef(n, k)))
|
C#
using System;
class GFG {
static int binomialCoeff( int n, int k)
{
int [, ] C = new int [n + 1, k + 1];
int i, j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= Math.Min(i, k); j++) {
if (j == 0 || j == i)
C[i, j] = 1;
else
C[i, j] = C[i - 1, j - 1] + C[i - 1, j];
}
}
return C[n, k];
}
static int min( int a, int b) { return (a < b) ? a : b; }
public static void Main()
{
int n = 5, k = 2;
Console.WriteLine( "Value of C(" + n + "," + k
+ ") is " + binomialCoeff(n, k));
}
}
|
Javascript
<script>
function binomialCoeff(n, k)
{
var C = Array(n + 1).fill(0).map(
x => Array(k + 1).fill(0));;
var i, j;
for (i = 0; i <= n; i++)
{
for (j = 0; j <= min(i, k); j++)
{
if (j == 0 || j == i)
C[i][j] = 1;
else
C[i][j] = C[i - 1][j - 1] +
C[i - 1][j];
}
}
return C[n][k];
}
function min(a, b)
{
return (a < b) ? a : b;
}
var n = 5, k = 2;
document.write( "Value of C(" + n + "," + k +
") is " + binomialCoeff(n, k));
</script>
|
PHP
<?php
function binomialCoeff( $n , $k )
{
$C = array ( array ());
$i ; $j ;
for ( $i = 0; $i <= $n ; $i ++)
{
for ( $j = 0; $j <= min( $i , $k ); $j ++)
{
if ( $j == 0 || $j == $i )
$C [ $i ][ $j ] = 1;
else
$C [ $i ][ $j ] = $C [ $i - 1][ $j - 1] +
$C [ $i - 1][ $j ];
}
}
return $C [ $n ][ $k ];
}
$n = 5;
$k = 2;
echo "Value of C(" , $n , " " , $k , ") is" , " "
, binomialCoeff( $n , $k ) ;
?>
|
Output
Value of C[5][2] is 10
Time Complexity: O(n*k)
Auxiliary Space: O(n*k)
Following is a space-optimized version of the above code. The following code only uses O(k). Thanks to AK for suggesting this method.
C++
#include <bits/stdc++.h>
using namespace std;
int binomialCoeff( int n, int k)
{
int C[k + 1];
memset (C, 0, sizeof (C));
C[0] = 1;
for ( int i = 1; i <= n; i++)
{
for ( int j = min(i, k); j > 0; j--)
C[j] = C[j] + C[j - 1];
}
return C[k];
}
int main()
{
int n = 5, k = 2;
cout << "Value of C(" << n << "," << k << ")" << "is " <<binomialCoeff(n, k);
return 0;
}
|
C
#include <stdio.h>
int binomialCoeff( int n, int k)
{
int C[k + 1];
memset (C, 0, sizeof (C));
C[0] = 1;
for ( int i = 1; i <= n; i++) {
for ( int j = min(i, k); j > 0; j--)
C[j] = C[j] + C[j - 1];
}
return C[k];
}
int main()
{
int n = 5, k = 2;
printf ( "Value of C(%d, %d) is %d " , n, k,
binomialCoeff(n, k));
return 0;
}
|
Java
import java.util.*;
class GFG {
static int binomialCoeff( int n, int k)
{
int C[] = new int [k + 1 ];
C[ 0 ] = 1 ;
for ( int i = 1 ; i <= n; i++) {
for ( int j = Math.min(i, k); j > 0 ; j--)
C[j] = C[j] + C[j - 1 ];
}
return C[k];
}
public static void main(String[] args)
{
int n = 5 , k = 2 ;
System.out.printf( "Value of C(%d, %d) is %d " , n, k,
binomialCoeff(n, k));
}
}
|
Python3
def binomialCoeff(n, k):
C = [ 0 for i in range (k + 1 )]
C[ 0 ] = 1
for i in range ( 1 , n + 1 ):
j = min (i, k)
while (j > 0 ):
C[j] = C[j] + C[j - 1 ]
j - = 1
return C[k]
n = 5
k = 2
print ( "Value of C(%d,%d) is %d" % (n, k, binomialCoeff(n, k)))
|
C#
using System;
class GFG {
static int binomialCoeff( int n, int k)
{
int [] C = new int [k + 1];
C[0] = 1;
for ( int i = 1; i <= n; i++) {
for ( int j = Math.Min(i, k); j > 0; j--)
C[j] = C[j] + C[j - 1];
}
return C[k];
}
public static void Main()
{
int n = 5, k = 2;
Console.WriteLine( "Value of C(" + n + " " + k
+ ") is " + binomialCoeff(n, k));
}
}
|
Javascript
<script>
function binomialCoeff(n, k)
{
let C = new Array(k + 1);
C.fill(0);
C[0] = 1;
for (let i = 1; i <= n; i++)
{
for (let j = Math.min(i, k); j > 0; j--)
C[j] = C[j] + C[j - 1];
}
return C[k];
}
let n = 5, k = 2;
document.write( "Value of C(" + n + " " +
k + ") is " + binomialCoeff(n, k));
</script>
|
PHP
<?php
function binomialCoeff( $n , $k )
{
$C = array_fill (0, $k + 1, 0);
$C [0] = 1;
for ( $i = 1; $i <= $n ; $i ++)
{
for ( $j = min( $i , $k ); $j > 0; $j --)
$C [ $j ] = $C [ $j ] + $C [ $j - 1];
}
return $C [ $k ];
}
$n = 5; $k = 2;
echo "Value of C[$n, $k] is " .
binomialCoeff( $n , $k );
?>
|
Output
Value of C(5, 2) is 10
Time Complexity: O(n*k)
Auxiliary Space: O(k)
Explanation:
1==========>> n = 0, C(0,0) = 1
1–1========>> n = 1, C(1,0) = 1, C(1,1) = 1
1–2–1======>> n = 2, C(2,0) = 1, C(2,1) = 2, C(2,2) = 1
1–3–3–1====>> n = 3, C(3,0) = 1, C(3,1) = 3, C(3,2) = 3, C(3,3)=1
1–4–6–4–1==>> n = 4, C(4,0) = 1, C(4,1) = 4, C(4,2) = 6, C(4,3)=4, C(4,4)=1
So here every loop on i, builds i’th row of pascal triangle, using (i-1)th row
At any time, every element of array C will have some value (ZERO or more) and in the next iteration, the value for those elements comes from the previous iteration.
In statement,
C[j] = C[j] + C[j-1]
The right-hand side represents the value coming from the previous iteration (A row of Pascal’s triangle depends on the previous row). The left-Hand side represents the value of the current iteration which will be obtained by this statement.
Let's say we want to calculate C(4, 3),
i.e. n=4, k=3:
All elements of array C of size 4 (k+1) are
initialized to ZERO.
i.e. C[0] = C[1] = C[2] = C[3] = C[4] = 0;
Then C[0] is set to 1
For i = 1:
C[1] = C[1] + C[0] = 0 + 1 = 1 ==>> C(1,1) = 1
For i = 2:
C[2] = C[2] + C[1] = 0 + 1 = 1 ==>> C(2,2) = 1
C[1] = C[1] + C[0] = 1 + 1 = 2 ==>> C(2,1) = 2
For i=3:
C[3] = C[3] + C[2] = 0 + 1 = 1 ==>> C(3,3) = 1
C[2] = C[2] + C[1] = 1 + 2 = 3 ==>> C(3,2) = 3
C[1] = C[1] + C[0] = 2 + 1 = 3 ==>> C(3,1) = 3
For i=4:
C[4] = C[4] + C[3] = 0 + 1 = 1 ==>> C(4,4) = 1
C[3] = C[3] + C[2] = 1 + 3 = 4 ==>> C(4,3) = 4
C[2] = C[2] + C[1] = 3 + 3 = 6 ==>> C(4,2) = 6
C[1] = C[1] + C[0] = 3 + 1 = 4 ==>> C(4,1) = 4
C(4,3) = 4 is would be the answer in our example.
Memoization Approach: The idea is to create a lookup table and follow the recursive top-down approach. Before computing any value, we check if it is already in the lookup table. If yes, we return the value. Else we compute the value and store it in the lookup table. Following is the Top-down approach of dynamic programming to finding the value of the Binomial Coefficient.
C++
#include <bits/stdc++.h>
using namespace std;
int binomialCoeffUtil( int n, int k, int ** dp)
{
if (dp[n][k] != -1)
return dp[n][k];
if (k == 0) {
dp[n][k] = 1;
return dp[n][k];
}
if (k == n) {
dp[n][k] = 1;
return dp[n][k];
}
dp[n][k] = binomialCoeffUtil(n - 1, k - 1, dp) +
binomialCoeffUtil(n - 1, k, dp);
return dp[n][k];
}
int binomialCoeff( int n, int k)
{
int ** dp;
dp = new int *[n + 1];
for ( int i = 0; i < (n + 1); i++) {
dp[i] = new int [k + 1];
}
for ( int i = 0; i < (n + 1); i++) {
for ( int j = 0; j < (k + 1); j++) {
dp[i][j] = -1;
}
}
return binomialCoeffUtil(n, k, dp);
}
int main()
{
int n = 5, k = 2;
cout << "Value of C(" << n << ", " << k << ") is "
<< binomialCoeff(n, k) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int binomialCoeffUtil( int n, int k,
Vector<Integer> []dp)
{
if (dp[n].get(k) != - 1 )
return dp[n].get(k);
if (k == 0 )
{
dp[n].add(k, 1 );
return dp[n].get(k);
}
if (k == n)
{
dp[n].add(k, 1 );
return dp[n].get(k);
}
dp[n].add(k, binomialCoeffUtil(n - 1 ,
k - 1 , dp) +
binomialCoeffUtil(n - 1 ,
k, dp));
return dp[n].get(k);
}
static int binomialCoeff( int n, int k)
{
Vector<Integer> []dp = new Vector[n+ 1 ];
for ( int i = 0 ; i < (n + 1 ); i++)
{
dp[i] = new Vector<Integer>();
for ( int j = 0 ; j <= k; j++)
dp[i].add(- 1 );
}
return binomialCoeffUtil(n, k, dp);
}
public static void main(String[] args)
{
int n = 5 , k = 2 ;
System.out.print( "Value of C(" + n +
", " + k + ") is " +
binomialCoeff(n, k) + "\n" );
}
}
|
Python3
def binomialCoeffUtil(n, k, dp):
if dp[n][k] ! = - 1 :
return dp[n][k]
if k = = 0 :
dp[n][k] = 1
return dp[n][k]
if k = = n:
dp[n][k] = 1
return dp[n][k]
dp[n][k] = (binomialCoeffUtil(n - 1 , k - 1 , dp) +
binomialCoeffUtil(n - 1 , k, dp))
return dp[n][k]
def binomialCoeff(n, k):
dp = [ [ - 1 for y in range (k + 1 ) ]
for x in range (n + 1 ) ]
return binomialCoeffUtil(n, k, dp)
n = 5
k = 2
print ( "Value of C(" + str (n) +
", " + str (k) + ") is" ,
binomialCoeff(n, k))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int binomialCoeffUtil( int n, int k,
List< int > []dp)
{
if (dp[n][k] != -1)
return dp[n][k];
if (k == 0)
{
dp[n][k] = 1;
return dp[n][k];
}
if (k == n)
{
dp[n][k] = 1;
return dp[n][k];
}
dp[n][k] = binomialCoeffUtil(n - 1,
k - 1, dp) +
binomialCoeffUtil(n - 1,
k, dp);
return dp[n][k];
}
static int binomialCoeff( int n, int k)
{
List< int > []dp = new List< int >[n + 1];
for ( int i = 0; i < (n + 1); i++)
{
dp[i] = new List< int >();
for ( int j = 0; j <= k; j++)
dp[i].Add(-1);
}
return binomialCoeffUtil(n, k, dp);
}
public static void Main(String[] args)
{
int n = 5, k = 2;
Console.Write( "Value of C(" + n +
", " + k + ") is " +
binomialCoeff(n, k) + "\n" );
}
}
|
Javascript
<script>
function binomialCoeffUtil(n, k, dp)
{
if (dp[n][k] != -1)
return dp[n][k];
if (k == 0)
{
dp[n][k] = 1;
return dp[n][k];
}
if (k == n)
{
dp[n][k] = 1;
return dp[n][k];
}
dp[n][k] = binomialCoeffUtil(n - 1,
k - 1, dp) +
binomialCoeffUtil(n - 1,
k, dp);
return dp[n][k];
}
function binomialCoeff(n, k)
{
let dp = new Array(n + 1);
for (let i = 0; i < (n + 1); i++)
{
dp[i] = [];
for (let j = 0; j <= k; j++)
dp[i].push(-1);
}
return binomialCoeffUtil(n, k, dp);
}
let n = 5, k = 2;
document.write( "Value of C(" + n +
", " + k + ") is " +
binomialCoeff(n, k) + "\n" );
</script>
|
Time Complexity: O(n*k)
Auxiliary Space: O(n*k)
Output
Value of C(5, 2) is 10
Cancellation of factors between numerator and denominator:
nCr = (n-r+1)*(n-r+2)*….*n / (r!)
Create an array arr of numbers from n-r+1 to n which will be of size r. As nCr is always an integer, all numbers in the denominator should cancel with the product of the numerator (represented by arr).
for i = 1 to i = r,
search arr, if arr[j] and i have gcd>1, divide both by the gcd and when i becomes 1, stop the search
Now, the answer is just the product of arr, whose value mod 10^9+7 can be found using a single pass and the formula use (a*b)%mod = (a%mod * b%mod)%mod
C++
#include <bits/stdc++.h>
using namespace std;
int gcd( int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
int nCr( int n, int r)
{
if (r > n)
return 0;
if (r > n - r)
r = n - r;
int mod = 1000000007;
int arr[r];
for ( int i = n - r + 1; i <= n; i++) {
arr[i + r - n - 1] = i;
}
long int ans = 1;
for ( int k = 1; k < r + 1; k++) {
int j = 0, i = k;
while (j < r) {
int x = gcd(i, arr[j]);
if (x > 1) {
arr[j] /= x;
i /= x;
}
if (i == 1)
break ;
j += 1;
}
}
for ( int i : arr)
ans = (ans * i) % mod;
return ( int )ans;
}
int main()
{
int n = 5, r = 2;
cout << "Value of C(" << n << ", " << r << ") is "
<< nCr(n, r) << "\n" ;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int gcd( int a, int b)
{
if (b== 0 ) return a;
return gcd(b,a%b);
}
static int nCr( int n, int r)
{
if (r>n)
return 0 ;
if (r>n-r)
r = n-r;
int mod = 1000000007 ;
int [] arr = new int [r];
for ( int i=n-r+ 1 ; i<=n; i++)
{
arr[i+r-n- 1 ] = i;
}
long ans = 1 ;
for ( int k= 1 ;k<r+ 1 ;k++)
{
int j= 0 , i=k;
while (j<arr.length)
{
int x = gcd(i,arr[j]);
if (x> 1 )
{
arr[j] /= x;
i /= x;
}
if (i== 1 )
break ;
j += 1 ;
}
}
for ( int i : arr)
ans = (ans*i)%mod;
return ( int )ans;
}
public static void main(String[] args)
{
int n = 5 , r = 2 ;
System.out.print( "Value of C(" + n+ ", " + r+ ") is "
+nCr(n, r) + "\n" );
}
}
|
Python3
import math
class GFG:
def nCr( self , n, r):
def gcd(a,b):
if b = = 0 :
return a
return gcd(b,a % b)
if r>n:
return 0
if r>n - r:
r = n - r
mod = 10 * * 9 + 7
arr = list ( range (n - r + 1 ,n + 1 ))
ans = 1
for i in range ( 1 ,r + 1 ):
j = 0
while j< len (arr):
x = gcd(i,arr[j])
if x> 1 :
arr[j] / / = x
i / / = x
if arr[j] = = 1 :
del arr[j]
j - = 1
if i = = 1 :
break
j + = 1
for i in arr:
ans = (ans * i) % mod
return ans
n = 5
k = 2
ob = GFG()
print ( "Value of C(" + str (n) +
", " + str (k) + ") is" ,
ob.nCr(n, k))
|
C#
using System;
class GFG{
static int gcd( int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
static int nCr( int n, int r)
{
if (r > n)
return 0;
if (r > n - r)
r = n - r;
int mod = 1000000007;
int [] arr = new int [r];
for ( int i = n - r + 1; i <= n; i++)
{
arr[i + r - n - 1] = i;
}
long ans = 1;
for ( int k = 1; k < r + 1; k++)
{
int j = 0, i = k;
while (j < arr.Length)
{
int x = gcd(i,arr[j]);
if (x > 1)
{
arr[j] /= x;
i /= x;
}
if (i == 1)
break ;
j += 1;
}
}
foreach ( int i in arr)
ans = (ans * i) % mod;
return ( int )ans;
}
static public void Main()
{
int n = 5, r = 2;
Console.WriteLine( "Value of C(" + n +
", " + r + ") is " +
nCr(n, r) + "\n" );
}
}
|
Javascript
<script>
function gcd(a, b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
function nCr(n, r)
{
if (r > n)
return 0;
if (r > n - r)
r = n - r;
mod = 1000000007;
var arr = new Array(r);
for ( var i = n - r + 1; i <= n; i++)
{
arr[i + r - n - 1] = i;
}
var ans = 1;
for ( var k = 1; k < r + 1 ; k++)
{
var j = 0, i = k;
while (j < arr.length)
{
var x = gcd(i, arr[j]);
if (x > 1)
{
arr[j] /= x;
i /= x;
}
if (i == 1)
break ;
j += 1;
}
}
arr.forEach( function (i)
{
ans = (ans * i) % mod;
});
return ans;
}
var n = 5, r = 2;
document.write( "Value of C(" + n + ", " +
r + ") is " + nCr(n, r) + "\n" );
</script>
|
Output
Value of C(5, 2) is 10
Time Complexity: O(( min(r, n-r)^2 ) * log(n)), useful when n >> r or n >> (n-r)
Auxiliary Space: O(min(r, n-r))
See this for GCD in logarithmic time
Prime factorization of every number from 1 to n using Sieve of Eratosthenes :
1. Create an array SPF of size n+1 to the smallest prime factor of each number from 1 to n
Set SPF[i] = i for all i = 1 to i = n
2. Use Sieve of Eratosthenes:
for i = 2 to i = n:
if i is prime,
for all multiples j of i, j<=n:
if SPF[j] equals j, set SPF[j] = i
3. Once, we know the SPF of each number from 1 to n, we can find the prime factorization of any number from 1 to n in O(log(n)) time using recursive division by SPF until the number becomes 1
Now, nCr = (n-r+1)*(r+2)* ... *(n) / (r)!
4. Create a dictionary (or hashmap) to store the frequency of each prime in the prime factorization of the actual value of nCr.
5. So, just calculate the frequency of each prime in nCr and multiply them raised to the power of their frequency.
6. For the numerator, iterate through i = n-r+1 to i = n, and for all prime factors of i, store their frequency in a dictionary.
( prime_pow[prime_factor] += freq_in_i )
7. For the denominator, iterate through i = 1 to i = r and now subtract the frequency instead of adding.
8. Now, traverse the dictionary and multiply the answer to (prime ^ prime_pow[prime]) % (10^9 + 7)
ans = (ans * pow(prime, prime_pow[prime], mod) ) % mod
C++
#include <bits/stdc++.h>
using namespace std;
long int pow ( long int b, long int exp , long int mod)
{
long int ret = 1;
while ( exp > 0) {
if (( exp & 1) > 0)
ret = (ret * b) % mod;
b = (b * b) % mod;
exp >>= 1;
}
return ret;
}
int nCr( int n, int r)
{
if (r > n)
return 0;
if (n - r > r)
r = n - r;
int SPF[n + 1];
for ( int i = 1; i <= n; i++)
SPF[i] = i;
for ( int i = 4; i <= n; i += 2)
SPF[i] = 2;
for ( int i = 3; i * i < n + 1; i += 2) {
if (SPF[i] == i) {
for ( int j = i * i; j < n + 1; j += i)
if (SPF[j] == j) {
SPF[j] = i;
}
}
}
map< int , int > prime_pow;
for ( int i = r + 1; i < n + 1; i++) {
int t = i;
while (t > 1) {
if (!prime_pow[SPF[t]]) {
prime_pow[SPF[t]] = 1;
}
else
prime_pow[SPF[t]]++;
t /= SPF[t];
}
}
for ( int i = 1; i < n - r + 1; i++) {
int t = i;
while (t > 1) {
prime_pow[SPF[t]]--;
t /= SPF[t];
}
}
long int ans = 1, mod = 1000000007;
for ( auto it : prime_pow)
ans = (ans
* pow (it.first, prime_pow[it.first], mod))
% mod;
return ( int )ans;
}
int main()
{
int n = 5, r = 2;
cout << "Value of C(" << n << ", " << r << ") is "
<< nCr(n, r) << "\n" ;
return 0;
}
|
Java
import java.util.*;
class GFG {
static long pow( long b, long exp, long mod)
{
long ret = 1 ;
while (exp > 0 ) {
if ((exp & 1 ) > 0 )
ret = (ret * b) % mod;
b = (b * b) % mod;
exp >>= 1 ;
}
return ret;
}
static int nCr( int n, int r)
{
if (r > n)
return 0 ;
if (n - r > r)
r = n - r;
int [] SPF = new int [n + 1 ];
for ( int i = 1 ; i <= n; i++)
SPF[i] = i;
for ( int i = 4 ; i <= n; i += 2 )
SPF[i] = 2 ;
for ( int i = 3 ; i * i < n + 1 ; i += 2 )
{
if (SPF[i] == i)
{
for ( int j = i * i; j < n + 1 ; j += i)
if (SPF[j] == j) {
SPF[j] = i;
}
}
}
Map<Integer, Integer> prime_pow
= new HashMap<>();
for ( int i = r + 1 ; i < n + 1 ; i++)
{
int t = i;
while (t > 1 )
{
prime_pow.put(SPF[t],
prime_pow.getOrDefault(SPF[t], 0 ) + 1 );
t /= SPF[t];
}
}
for ( int i = 1 ; i < n - r + 1 ; i++)
{
int t = i;
while (t > 1 )
{
prime_pow.put(SPF[t],
prime_pow.get(SPF[t]) - 1 );
t /= SPF[t];
}
}
long ans = 1 , mod = 1000000007 ;
for ( int i : prime_pow.keySet())
ans = (ans * pow(i, prime_pow.get(i), mod))
% mod;
return ( int )ans;
}
public static void main(String[] args)
{
int n = 5 , r = 2 ;
System.out.print( "Value of C(" + n + ", " + r
+ ") is " + nCr(n, r) + "\n" );
}
}
|
Python3
import math
class GFG:
def nCr( self , n, r):
if r > n:
return 0
if n - r > r:
r = n - r
SPF = [i for i in range (n + 1 )]
for i in range ( 4 , n + 1 , 2 ):
SPF[i] = 2
for i in range ( 3 , n + 1 , 2 ):
if i * i > n:
break
if SPF[i] = = i:
for j in range (i * i, n + 1 , i):
if SPF[j] = = j:
SPF[j] = i
prime_pow = {}
for i in range (r + 1 , n + 1 ):
t = i
while t > 1 :
if not SPF[t] in prime_pow:
prime_pow[SPF[t]] = 1
else :
prime_pow[SPF[t]] + = 1
t / / = SPF[t]
for i in range ( 1 , n - r + 1 ):
t = i
while t > 1 :
prime_pow[SPF[t]] - = 1
t / / = SPF[t]
ans = 1
mod = 10 * * 9 + 7
for i in prime_pow:
ans = (ans * pow (i, prime_pow[i], mod)) % mod
return ans
n = 5
k = 2
ob = GFG()
print ( "Value of C(" + str (n) +
", " + str (k) + ") is" ,
ob.nCr(n, k))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static long pow( long b, long exp, long mod)
{
long ret = 1;
while (exp > 0) {
if ((exp & 1) > 0)
ret = (ret * b) % mod;
b = (b * b) % mod;
exp >>= 1;
}
return ret;
}
static int nCr( int n, int r)
{
if (r > n)
return 0;
if (n - r > r)
r = n - r;
int [] SPF = new int [n + 1];
for ( int i = 1; i <= n; i++)
SPF[i] = i;
for ( int i = 4; i <= n; i += 2)
SPF[i] = 2;
for ( int i = 3; i * i < n + 1; i += 2) {
if (SPF[i] == i) {
for ( int j = i * i; j < n + 1; j += i)
if (SPF[j] == j) {
SPF[j] = i;
}
}
}
Dictionary< int , int > prime_pow
= new Dictionary< int , int >();
for ( int i = r + 1; i < n + 1; i++) {
int t = i;
while (t > 1) {
if (prime_pow.ContainsKey(SPF[t])) {
prime_pow[SPF[t]]
= prime_pow[SPF[t]] + 1;
}
else {
prime_pow.Add(SPF[t], 1);
}
t /= SPF[t];
}
}
for ( int i = 1; i < n - r + 1; i++) {
int t = i;
while (t > 1) {
if (prime_pow.ContainsKey(SPF[t])) {
prime_pow[SPF[t]]
= prime_pow[SPF[t]] - 1;
}
t /= SPF[t];
}
}
long ans = 1, mod = 1000000007;
foreach ( int i in prime_pow.Keys)
ans
= (ans * pow(i, prime_pow[i], mod)) % mod;
return ( int )ans;
}
public static void Main(String[] args)
{
int n = 5, r = 2;
Console.Write( "Value of C(" + n + ", " + r + ") is "
+ nCr(n, r) + "\n" );
}
}
|
Javascript
<script>
function gcd(a, b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
function nCr(n, r)
{
if (r > n)
return 0;
if (r > n - r)
r = n - r;
var mod = 1000000007;
var arr = new Array(r);
for ( var i = n - r + 1; i <= n; i++) {
arr[i + r - n - 1] = i;
}
var ans = 1;
for ( var k = 1; k < r + 1; k++) {
var j = 0;
var i = k;
do {
var x = gcd(i, arr[j]);
if (x > 1) {
arr[j] /= x;
i /= x;
}
if (i == 1)
break ;
j += 1;
}
while (j < r);
}
arr.forEach( function (i, index) {
ans = (ans * i) % mod;
});
return ans;
}
var n = 5;
var r = 2;
document.write( "Value of C(" + n + ", " + r + ") is " + nCr(n, r) + "<br>" );
</script>
|
Output
Value of C(5, 2) is 10
Time Complexity: O(n*log(n)), so useful when r->n/2
Auxiliary Space: O(n)
See this for Prime factorization in O(log(n))
Another Approach: (Modular Inversion technique)
1. The general formula of nCr is ( n*(n-1)*(n-2)* … *(n-r+1) ) / (r!). We can directly use this formula to find nCr. But that will overflow out of bound. We need to find nCr mod m so that it doesn’t overflow. We can easily do it with modular arithmetic formula.
for the n*(n-1)*(n-2)* ... *(n-r+1) part we can use the formula,
(a*b) mod m = ((a % m) * (b % m)) % m
2. and for the 1/r! part, we need to find the modular inverse of every number from 1 to r. Then use the same formula above with a modular inverse of 1 to r. We can find modular inverse in O(r) time using the formula,
inv[1] = 1
inv[i] = − ⌊m/i⌋ * inv[m mod i] mod m
To use this formula, m has to be a prime.
In the practice problem, we need to show the answer with modulo 1000000007 which is a prime.
So, this technique will work.
C++
#include<bits/stdc++.h>
using namespace std;
int binomialCoeff( int n, int r)
{
if (r > n)
return 0;
long long int m = 1000000007;
long long int inv[r + 1] = { 0 };
inv[0] = 1;
if (r+1>=2)
inv[1] = 1;
for ( int i = 2; i <= r; i++) {
inv[i] = m - (m / i) * inv[m % i] % m;
}
int ans = 1;
for ( int i = 2; i <= r; i++) {
ans = ((ans % m) * (inv[i] % m)) % m;
}
for ( int i = n; i >= (n - r + 1); i--) {
ans = ((ans % m) * (i % m)) % m;
}
return ans;
}
int main()
{
int n = 5, r = 2;
cout << "Value of C(" << n << ", " << r << ") is "
<< binomialCoeff(n, r) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int binomialCoeff( int n, int r)
{
if (r > n)
return 0 ;
long m = 1000000007 ;
long inv[] = new long [r + 1 ];
inv[ 0 ] = 1 ;
if (r+ 1 >= 2 )
inv[ 1 ] = 1 ;
for ( int i = 2 ; i <= r; i++) {
inv[i] = m - (m / i) * inv[( int ) (m % i)] % m;
}
int ans = 1 ;
for ( int i = 2 ; i <= r; i++) {
ans = ( int ) (((ans % m) * (inv[i] % m)) % m);
}
for ( int i = n; i >= (n - r + 1 ); i--) {
ans = ( int ) (((ans % m) * (i % m)) % m);
}
return ans;
}
public static void main(String[] args)
{
int n = 5 , r = 2 ;
System.out.print( "Value of C(" + n+ ", " + r+ ") is "
+binomialCoeff(n, r) + "\n" );
}
}
|
Python3
def binomialCoeff(n, r):
if (r > n):
return 0
m = 1000000007
inv = [ 0 for i in range (r + 1 )]
inv[ 0 ] = 1
if (r + 1 > = 2 ):
inv[ 1 ] = 1
for i in range ( 2 , r + 1 ):
inv[i] = m - (m / / i) * inv[m % i] % m
ans = 1
for i in range ( 2 , r + 1 ):
ans = ((ans % m) * (inv[i] % m)) % m
for i in range (n, n - r, - 1 ):
ans = ((ans % m) * (i % m)) % m
return ans
n = 5
r = 2
print ( "Value of C(" ,n , "," , r , ") is " ,binomialCoeff(n, r))
|
C#
using System;
public class GFG
{
static int binomialCoeff( int n, int r)
{
if (r > n)
return 0;
long m = 1000000007;
long []inv = new long [r + 1];
inv[0] = 1;
if (r+1>=2)
inv[1] = 1;
for ( int i = 2; i <= r; i++) {
inv[i] = m - (m / i) * inv[( int ) (m % i)] % m;
}
int ans = 1;
for ( int i = 2; i <= r; i++) {
ans = ( int ) (((ans % m) * (inv[i] % m)) % m);
}
for ( int i = n; i >= (n - r + 1); i--) {
ans = ( int ) (((ans % m) * (i % m)) % m);
}
return ans;
}
public static void Main(String[] args)
{
int n = 5, r = 2;
Console.Write( "Value of C(" + n+ ", " + r+ ") is "
+binomialCoeff(n, r) + "\n" );
}
}
|
Javascript
<script>
function binomialCoeff(n, r) {
if (r > n)
return 0;
let m = 1000000007;
let inv = new Array(r + 1).fill(0);
inv[0] = 1;
if (r + 1 >= 2)
inv[1] = 1;
for (let i = 2; i <= r; i++) {
inv[i] = m - Math.floor(m / i) * inv[m % i] % m;
}
let ans = 1;
for (let i = 2; i <= r; i++) {
ans = ((ans % m) * (inv[i] % m)) % m;
}
for (let i = n; i >= (n - r + 1); i--) {
ans = ((ans % m) * (i % m)) % m;
}
return ans;
}
let n = 5, r = 2;
document.write( "Value of C(" + n + ", " + r + ") is "
+ binomialCoeff(n, r) + "<br>" );
</script>
|
Output
Value of C(5, 2) is 10
Time Complexity: O(n+k)
Auxiliary Space: O(k)
See this for Space and time-efficient Binomial Coefficient
References:
http://www.csl.mtu.edu/cs4321/www/Lectures/Lecture%2015%20-%20Dynamic%20Programming%20Binomial%20Coefficients.htm
https://cp-algorithms.com/algebra/module-inverse.html
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
24 Sep, 2023
Like Article
Save Article