直通BAT--数据结构与算法十(排列组合)


排列组合常考题型:

  • 传统排列组合题:高中数学知识
  • 卡特兰数应用:先详细了解卡特兰数原理


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 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;
     }
};

你可能感兴趣的:(c++,排列组合,数据结构,算法,C++)