不相交的握手
难度:
标签:
题目描述
代码结果
运行时间: 32 ms, 内存: 16.1 MB
/*
* Leetcode Problem 1259: Handshakes That Don't Cross
*
* Problem Statement:
* You are given an even number of people standing in a circle. Each person shakes hands with exactly one other person such that the handshakes do not cross. Determine the number of ways these handshakes can occur.
*
* Approach:
* This problem can be solved using dynamic programming with the help of Java Streams. We can use the concept of Catalan numbers which count the number of ways to correctly match parentheses, or in this case, the number of ways to arrange handshakes.
*
* The recurrence relation for Catalan numbers is:
* C(n) = sum(C(i) * C(n-1-i)) for i from 0 to n-1
*
* In this problem, we are asked to find the number of ways to arrange handshakes for 2n people.
*/
import java.util.stream.IntStream;
public class HandshakesThatDontCrossStream {
public int numberOfWays(int numPeople) {
if (numPeople % 2 != 0) return 0;
int n = numPeople / 2;
long[] dp = new long[n + 1];
dp[0] = 1;
IntStream.rangeClosed(1, n).forEach(i -> dp[i] = IntStream.range(0, i).mapToLong(j -> dp[j] * dp[i - 1 - j]).sum());
return (int) dp[n];
}
public static void main(String[] args) {
HandshakesThatDontCrossStream solution = new HandshakesThatDontCrossStream();
int numPeople = 6; // Example input
System.out.println(solution.numberOfWays(numPeople)); // Output should be 5
}
}
解释
方法:
这个题解使用了卡特兰数的公式。卡特兰数是一系列自然数,广泛用于计算在各种情境中不相交结构的数量。在这个问题中,我们要找到不相交的握手方式数,这可以用卡特兰数来解决。卡特兰数的第n项可以用公式 C(n) = (2n)! / ((n + 1)! * n!) 来计算。这里,n是握手的对数,即总人数的一半。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
题解中提到使用卡特兰数公式来解决问题,能否详细解释为什么不相交的握手问题可以用卡特兰数来描述?
▷🦆
在计算卡特兰数时,题解使用了阶乘的方法,这种方法在数字很大时是否会遇到性能瓶颈?
▷🦆
题解使用了模运算`(10**9 + 7)`来进行结果的返回,为什么选择这个特定的数值进行模运算?
▷🦆
卡特兰数的计算涉及到两次阶乘的除法,如何确保计算过程中不会出现除以零的异常?
▷