Given n persons sitting around a round table, each person can shake hands with exactly one other person. Find the number of ways such that no two handshakes cross each other.
n is always even.
Each person participates in exactly one handshake.
Examples:
Input: n = 2 Output: 1 Explanation: For 2 people, the possible non-crossing handshakes are: [1-2]
Input: n = 4 Output: 2 Explanation: For 4 people, the possible non-crossing handshakes are: [1–2], [3–4] [1–4], [2–3]
[Naive Approach] Using Recursion - O(2^n) Time O(n) Space
The Idea is to try all possible ways to form handshakes by fixing one person and pairing it with every possible valid person. Recursively solve for the remaining people.
C++
#include<iostream>#include<vector>usingnamespacestd;// function to find handshakesintcount(intn){// if n is odd, no valid handshakeif(n%2==1)return0;// base caseif(n==0)return1;intres=0;// try all possible pairingsfor(inti=0;i<n;i+=2){res+=count(i)*count(n-2-i);}returnres;}// Driver Codeintmain(){intn=4;cout<<count(n);return0;}
C
#include<stdio.h>// function to find handshakesintcount(intn){// if n is odd, no valid handshakeif(n%2==1)return0;// base caseif(n==0)return1;intres=0;// try all possible pairingsfor(inti=0;i<n;i+=2){res+=count(i)*count(n-2-i);}returnres;}// Driver Codeintmain(){intn=4;printf("%d",count(n));return0;}
Java
publicclassGfG{// function to find handshakesstaticintcount(intn){// if n is odd, no valid handshakeif(n%2==1)return0;// base caseif(n==0)return1;intres=0;// try all possible pairingsfor(inti=0;i<n;i+=2){res+=count(i)*count(n-2-i);}returnres;}// Driver Codepublicstaticvoidmain(String[]args){intn=4;System.out.println(count(n));}}
Python
# function to find handshakesdefcount(n):# if n is odd, no valid handshakeifn%2==1:return0# base caseifn==0:return1res=0# try all possible pairingsforiinrange(0,n,2):res+=count(i)*count(n-2-i)returnres# Driver Codeif__name__=="__main__":n=4print(count(n))
C#
usingSystem;publicclassGfG{// function to find handshakespublicintcount(intn){if(n%2==1)return0;if(n==0)return1;intres=0;for(inti=0;i<n;i+=2){res+=count(i)*count(n-2-i);}returnres;}// Driver CodepublicstaticvoidMain(){intn=4;GfGobj=newGfG();Console.WriteLine(obj.count(n));}}
JavaScript
// function to find handshakesfunctioncount(n){// if n is odd, no valid handshakeif(n%2===1)return0;// base caseif(n===0)return1;letres=0;// try all possible pairingsfor(leti=0;i<n;i+=2){res+=count(i)*count(n-2-i);}returnres;}// Driver Codeletn=4;console.log(count(n));
Output
2
Time Complexity : O(2^n) Auxiliary Space : O(n)
[Better Approach] Using Bottom-Up Dynamic Programming - (n^2) Time O(n) Space
The Idea is to use a DP array to store results of subproblems and build the solution iteratively using the Catalan recurrence.
C++
#include<iostream>#include<vector>usingnamespacestd;// function to find no of handshakesintcount(intn){// if n is odd, return 0if(n%2==1)return0;vector<int>dp(n+1,0);// base casedp[0]=1;// fill dp arrayfor(inti=2;i<=n;i+=2){for(intj=0;j<i;j+=2){dp[i]+=dp[j]*dp[i-2-j];}}returndp[n];}// Driver Codeintmain(){intn=4;cout<<count(n);return0;}
C
#include<stdio.h>#include<stdlib.h>// function to find no of handshakesintcount(intn){// if n is odd, return 0if(n%2==1)return0;int*dp=calloc(n+1,sizeof(int));// base casedp[0]=1;// fill dp arrayfor(inti=2;i<=n;i+=2){for(intj=0;j<i;j+=2){dp[i]+=dp[j]*dp[i-2-j];}}intresult=dp[n];free(dp);returnresult;}// Driver Codeintmain(){intn=4;printf("%d",count(n));return0;}
Java
importjava.util.*;publicclassGfG{// function to find no of handshakespublicstaticintcount(intn){// if n is odd, return 0if(n%2==1)return0;int[]dp=newint[n+1];// base casedp[0]=1;// fill dp arrayfor(inti=2;i<=n;i+=2){for(intj=0;j<i;j+=2){dp[i]+=dp[j]*dp[i-2-j];}}returndp[n];}publicstaticvoidmain(String[]args){intn=4;System.out.println(count(n));}}
Python
# function to find no of handshakesdefcount(n):# if n is odd, return 0ifn%2==1:return0dp=[0]*(n+1)# base casedp[0]=1# fill dp arrayforiinrange(2,n+1,2):forjinrange(0,i,2):dp[i]+=dp[j]*dp[i-2-j]returndp[n]# Driver Codeif__name__=="__main__":n=4print(count(n))
// function to find no of handshakesfunctioncount(n){// if n is odd, return 0if(n%2===1)return0;letdp=newArray(n+1).fill(0);// base casedp[0]=1;// fill dp arrayfor(leti=2;i<=n;i+=2){for(letj=0;j<i;j+=2){dp[i]+=dp[j]*dp[i-2-j];}}returndp[n];}// Driver Codeletn=4;console.log(count(n));
Output
2
Time Complexity : O(n^2) Auxiliary Space : O(n)
[Expected Approach] Using Catalan Formula - O(n) Time O(1) Space
The idea is to use the direct formula of Catalan Number: C_k = \frac{1}{k+1} \times \binom{2k}{k}, where k = n / 2.
C++
#include<iostream>#include<vector>usingnamespacestd;// function to find handshakesintcount(intn){// if n is odd, return 0if(n%2==1)return0;intk=n/2;longlongres=1;// compute (2k C k)for(inti=0;i<k;i++){res=res*(2*k-i);res=res/(i+1);}// divide by (k + 1)res=res/(k+1);returnres;}// Driver Codeintmain(){intn=4;cout<<count(n);return0;}
C
#include<stdio.h>// function to find handshakesintcount(intn){// if n is odd, return 0if(n%2==1)return0;intk=n/2;longlongres=1;// compute (2k C k)for(inti=0;i<k;i++){res*=(2*k-i);res/=(i+1);}// divide by (k + 1)res/=(k+1);returnres;}// Driver Codeintmain(){intn=4;printf("%d",count(n));return0;}
Java
importjava.util.*;publicclassGfG{// function to find handshakespublicstaticlongcount(intn){// if n is odd, return 0if(n%2==1)return0;intk=n/2;longres=1;// compute (2k C k)for(inti=0;i<k;i++){res*=(2*k-i);res/=(i+1);}// divide by (k + 1)res/=(k+1);returnres;}publicstaticvoidmain(String[]args){intn=4;System.out.println(count(n));}}
Python
defcount(n):# if n is odd, return 0ifn%2==1:return0k=n//2res=1# compute (2k C k)foriinrange(k):res*=(2*k-i)res//=(i+1)# divide by (k + 1)res//=(k+1)returnres# Driver Codeif__name__=="__main__":n=4print(count(n))
C#
usingSystem;publicclassGfG{// function to find handshakespublicintcount(intn){if(n%2==1)return0;intk=n/2;longres=1;for(inti=0;i<k;i++){res*=(2L*k-i);res/=(i+1);}res/=(k+1);return(int)res;}publicstaticvoidMain(){intn=4;GfGobj=newGfG();Console.WriteLine(obj.count(n));}}
JavaScript
functioncount(n){// if n is odd, return 0if(n%2===1)return0;letk=Math.floor(n/2);letres=1;// compute (2k C k)for(leti=0;i<k;i++){res*=(2*k-i);res=Math.floor(res/(i+1));}// divide by (k + 1)res=Math.floor(res/(k+1));returnMath.floor(res);}// Driver Codeletn=4;console.log(count(n));