排列组合

1方格移动

在XxY的方格中,以左上角格子为起点,右下角格子为终点,每次只能向下走或者向右走,请问一共有多少种不同的走法

给定两个正整数int x,int y,请返回走法数目。保证x+y小于等于12。

测试样例:
2,2
返回:2
import java.util.*;
 
public class Robot {
    public int countWays(int x, int y) {
        int n = x+y-2;
        int m = x-1;
        int res = go(n)/(go(m)*go(n-m));
        return res;
    }
 
    private int go(int n) {
        int res = 1;
        for(int i=1;i<=n;i++){
            res *= i;
        }
        return res;
    }
}
import java.util.*;
 
public class Robot {
    public int countWays(int x, int y) {
        // write code here
        int res = 1;
        for(int i=1; i<x; i++){
            res = res*(y+i-1)/i;
        }
        return res;
    }
}

2战队问题

n个人站队,他们的编号依次从1到n,要求编号为a的人必须在编号为b的人的左边,但不要求一定相邻,请问共有多少种排法?第二问如果要求a必须在b的左边,并且一定要相邻,请问一共有多少种排法?

给定人数n及两个人的编号ab,请返回一个两个元素的数组,其中两个元素依次为两个问题的答案。保证人数小于等于10。

测试样例:
7,1,2
返回:[2520,720]
import java.util.*;
 
public class StandInLine {
    public int[] getWays(int n, int a, int b) {
        int k[] = new int[2];
        k[0] = go(n)/2;
         k[1] = go(n-1);
        return k;
     
}
 
    private int go(int n) {
        int res = 1;
        for(int i=1;i<=n;i++){
            res *= i;
        }
        return res;
    }
}

3孤傲的A

A(A也是他的编号)是一个孤傲的人,在一个n个人(其中编号依次为1到n)的队列中,他于其中的标号为b和标号c的人都有矛盾,所以他不会和他们站在相邻的位置。现在问你满足A的要求的对列有多少种?

给定人数n和三个人的标号A,bc,请返回所求答案,保证人数小于等于11且大于等于3。

测试样例:
6,1,2,3
288
import java.util.*;
 
public class LonelyA {
    public int getWays(int n, int A, int b, int c) {
      int z = go(n);
      int a = go(n-1)*4;
      int q = go(n-2);
      return z-a+2*q;
     
}
 
    private int go(int n) {
        int res = 1;
        for(int i=1;i<=n;i++){
            res *= i;
        }
        return res;
    }
}

4分糖果

n颗相同的糖果,分给m个人,每人至少一颗,问有多少种分法。

给定nm,请返回方案数,保证n小于等于12,且m小于等于n。

测试样例:
10,3
返回:36
import java.util.*;
 
public class Distribution {
    public int getWays(int n, int m) {
        // write code here
        return C(n-1,m-1);
    }
    public int C(int n,int m)
    {
        int res1=1,res2=1;
        for(int i=n;i>n-m;i--)
        {
            res1*=i;
        }
        for(int i=1;i<=m;i++)
        {
            res2*=i;
        }
        return res1/res2;
    }
}

 

import java.util.*;
 
public class Distribution {
    public int getWays(int n, int m) {
        // write code here
        int ans = 1;
        for(int i = 1;i < m;++ i){
            ans = ans * (n-i) / i;
        }
        return ans;
    }
}

 5括号序列

假设有n对左右括号,请求出合法的排列有多少个?合法是指每一个括号都可以找到与之配对的括号,比如n=1时,()是合法的,但是)(为不合法。

给定一个整数n,请返回所求的合法排列数。保证结果在int范围内。

测试样例:
1
返回:1
import java.util.*;
 
public class Parenthesis {
    public int countLegalWays(int n) {
        // write code here
        int temp1=1;
        for(int i=n+1;i<=2*n;i++)
        {
            temp1*=i;
        }
        int temp2=1;
        for(int i=1;i<=n;i++)
        {
            temp2*=i;
        }
        return temp1/(temp2*(n+1));
         
    }
}

6进出栈

n个数进出栈的顺序有多少种?假设栈的容量无限大。

给定一个整数n,请返回所求的进出栈顺序个数。保证结果在int范围内。

测试样例:
1
返回:1

进栈相当于左括号,出战相当于右括号
import java.util.*;
 
public class Stack {
    public int countWays(int n) {
        // write code here
        int temp1=1;
        for(int i=n+1;i<=2*n;i++)
        {
            temp1*=i;
        }
        int temp2=1;
        for(int i=1;i<=n;i++)
         {
            temp2*=i;
        }
        return temp1/(temp2*(n+1));
    }
}

7排队买票

2n个人排队买票,n个人拿5块钱,n个人拿10块钱,票价是5块钱1张,每个人买一张票,售票员手里没有零钱,问有多少种排队方法让售票员可以顺利卖票。

给定一个整数n,请返回所求的排队方案个数。保证结果在int范围内。

测试样例:
1
返回:1

5块钱相当于左括号,10块钱相当于右括号
import java.util.*;
 
public class Stack {
    public int countWays(int n) {
        // write code here
        int temp1=1;
        for(int i=n+1;i<=2*n;i++)
        {
            temp1*=i;
        }
        int temp2=1;
        for(int i=1;i<=n;i++)
         {
            temp2*=i;
        }
        return temp1/(temp2*(n+1));
    }
}

8二叉树统计

求n个无差别的节点构成的二叉树有多少种不同的结构?

给定一个整数n,请返回不同结构的二叉树的个数。保证结果在int范围内。

测试样例:
1
返回:1

思路:卡特兰重要公式2

import java.util.*;
 
public class Stack {
    public int countWays(int n) {
        // write code here
        int temp1=1;
        for(int i=n+1;i<=2*n;i++)
        {
            temp1*=i;
        }
        int temp2=1;
        for(int i=1;i<=n;i++)
         {
            temp2*=i;
        }
        return temp1/(temp2*(n+1));
    }
}

9高矮排列

12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?

给定一个偶数n,请返回所求的排列方式个数。保证结果在int范围内。

测试样例:
1
返回:1

import java.util.*;
 
public class Stack {
    public int countWays(int n) {
        // write code here
        int temp1=1;
        for(int i=n+1;i<=2*n;i++)
        {
            temp1*=i;
        }
        int temp2=1;
        for(int i=1;i<=n;i++)
         {
            temp2*=i;
        }
        return temp1/(temp2*(n+1));
    }
}

10装错信封

有n个信封,包含n封信,现在把信拿出来,再装回去,要求每封信不能装回它原来的信封,问有多少种装法?

给定一个整数n,请返回装发个数,为了防止溢出,请返回结果Mod 1000000007的值。保证n的大小小于等于300。

测试样例:
2
返回:1
import java.util.*;
 
public class CombineByMistake {
    public int countWays(int n) {
        if(n == 1){
            return 0;
        }
        long[] res = new long[n+1];
        res[2] = 1;
        for(int i=3;i<=n;i++){
            res[i] = (i-1)*(res[i-1] + res[i-2])%1000000007;
        }
        return (int)res[n];
    }
}

 

import java.util.*;
 
public class CombineByMistake {
    final static int RANGE = 1000000007;
    private static int[] arr = new int[301];
    public int countWays(int n) {
        // write code here
        return f(n);
    }
     
    public int f(int n) {
        if (arr[n] != 0)
            return arr[n];
        else if (n == 1)
            return 0;
        else if (n == 2)
            return 1;
        else if (n == 3)
            return 2;
        else {
            int f1 = f(n-1);
            int f2 = f(n-2);
             
            long res = (f1 + f2) % RANGE;
            res = res * (n-1) % RANGE;
             
            arr[n] = (int)res;
             
            return (int)res;
        }
    }
}

 

import java.util.*;
import java.math.BigInteger;
public class CombineByMistake {
  public int countWays(int n) {
        if(n==1){
            return 0;
        }else if(n==2){
            return 1;
        }else{
            long pre = 0;
            long last = 1;
            for(int i=3; i<=n; i++){
                long tmp = ((i-1)*(pre + last))%1000000007;
                pre = last;
                last = tmp;
            }
            return (int)last;
        }
    }
}

 

import java.util.*;
 
public class CombineByMistake {
    public int countWays(int n) {
        if (n <= 1)
            return 0;
        if (n == 2)
            return 1;
        int pre = 0, last = 1, res = 0;
        for (int i = 3; i <= n; i++) {
            res = (int) (((long)(i - 1) * (long)(pre + last)) % 1000000007);
            pre = last;
            last = res;
        }
        return res;
    }
}

 



posted @ 2017-05-17 16:05  临江仙zhe  阅读(208)  评论(0)    收藏  举报