排列组合常考题型:
- 传统排列组合题:高中数学知识
- 卡特兰数应用:先详细了解卡特兰数原理
1.括号合法问题
//假设有n对左右括号,请求出合法的排列有多少个?合法是指每一个括号都可以找到与之配对的括号,比如n = 1时,()是合法的,但是)(为不合法。
//
//给定一个整数n,请返回所求的合法排列数。保证结果在int范围内。
//
//测试样例:
// 1
//返回:1
class ParenthesisSequence {
public:
int countLegalWays(int n) {
long res = 1;
for (int i = 2 * n; i > n; --i){
res *= i;
}
for (int i = n+1; i > 0; --i){
res /= i;
}
return res;
}
};
2.进出栈问题
//n个数进出栈的顺序有多少种?假设栈的容量无限大。
//
//给定一个整数n,请返回所求的进出栈顺序个数。保证结果在int范围内。
//
//测试样例:
//1
//返回:1
class InOutStack {
public:
int countWays(int n) {
int res = 1;
for (int i = 2 * n; i > n; --i){
res *= i;
}
for (int j = n+1; j > 0; --j){
res /= j;
}
return res;
}
};
3.二叉树结构问题
//求n个无差别的节点构成的二叉树有多少种不同的结构?
//
//给定一个整数n,请返回不同结构的二叉树的个数。保证结果在int范围内。
//
//测试样例:
//1
//返回:1
class TreeCount {
public:
int countWays(int n) {
int res = 1;
for (int i = 2 * n; i > n; --i){
res *= i;
}
for (int j = n + 1; j > 0; --j){
res /= j;
}
return res;
}
};
4.高矮排列问题
//12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?
//
//给定一个偶数n,请返回所求的排列方式个数。保证结果在int范围内。
//
//测试样例:
//1
//返回:1
class HighShortSort {
public:
int countWays(int n) {
int res = 1;
for (int i = n; i > n/2; --i){
res *= i;
}
for (int j = n/2 + 1; j > 0; --j){
res /= j;
}
return res;
}
};
5.排队买票问题
//2n个人排队买票,n个人拿5块钱,n个人拿10块钱,票价是5块钱1张,每个人买一张票,售票员手里没有零钱,问有多少种排队方法让售票员可以顺利卖票。
//
//给定一个整数n,请返回所求的排队方案个数。保证结果在int范围内。
//
//测试样例:
//1
//返回:1
class BuyTickets {
public:
int countWays(int n) {
int res = 1;
for (int i = 2 * n; i > n; --i){
res *= i;
}
for (int j = n + 1; j > 0; --j){
res /= j;
}
return res;
}
};
6.错装信封问题
//有n个信封,包含n封信,现在把信拿出来,再装回去,要求每封信不能装回它原来的信封,问有多少种装法 ?
//
//给定一个整数n,请返回装发个数,为了防止溢出,请返回结果Mod 1000000007的值。保证n的大小小于等于300。
//
//测试样例:
//2
//返回:1
//分析:
//1.f(n)表示n封信的方法数
//2.将信n放在第i个信封内,i有n - 1中选择
//3.分两种情况:将第i封信放在第n个信封则剩下n - 2封信,即f(n - 2)
//其实就是假设n是另一个i位,然后i不能放在该位,剩下为f(n - 1)
//4.可得f(n) = (n - 1)*(f(n - 1) + f(n - 2))
class CombineEnvelopeByMistake {
public:
int countWays(int n) {
if (n <= 1){
return 0;
}
if (n == 2){
return 1;
}
vector<long> arr(n + 1, 0);
arr[2] = 1;
for (int i = 3; i <= n; ++i){
arr[i] = (i - 1)*(arr[i - 1] + arr[i - 2]) % 1000000007;
}
return arr[n] % 1000000007;
}
};