【每周一算】杨辉三角(巴斯卡三角形)

杨辉三角,是二项式系数在三角形中的一种几何排列,中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623----1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。

特性:

  1. 每个数等于它上方两数之和。
  2. 每行数字左右对称,由1开始逐渐变大。
  3. 第n行的数字有n项。
  4. 第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。
  5. 第n行的第m个数和第n-m+1个数相等 ,为组合数性质之一。
  6. 每个数字等于上一行的左右两个数字之和。可用此性质写出整个杨辉三角。即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和,这也是组合数的性质之一。即 C(n+1,i)=C(n,i)+C(n,i-1)
  7. (a+b)n的展开式中的各项系数依次对应杨辉三角的第(n+1)行中的每一项。
  8. 将第2n+1行第1个数,跟第2n+2行第3个数、第2n+3行第5个数……连成一线,这些数的和是第4n+1个斐波那契数;将第2n行第2个数(n>1),跟第2n-1行第4个数、第2n-2行第6个数……这些数之和是第4n-2个斐波那契数。
  9. 将第n行的各数值,分别乘以10的列数m-1次方,然后把这些数值相加的和等于11的n-1次方。例子:第11行数分别为1,10,45,120,210,252,210,120,45,10,1,则11^10 = 1*10^0+10*10^1+45*10^2+...+1*10^10 =25937424601

解题,可以用第6点特性写出杨辉三角。

代码实现:

package com.jandmin.demo.leetcode;

/**
 * @description: 杨辉三角
 *               杨辉三角,是二项式系数在三角形中的一种几何排列。在欧洲,这个表叫做帕斯卡三角形。
 *               帕斯卡(1623----1662)是在1654年发现这一规律的,比杨辉要迟393年,比贾宪迟600年。
 *               杨辉三角是中国古代数学的杰出研究成果之一,它把二项式系数图形化,
 *               把组合数内在的一些代数性质直观地从图形中体现出来,是一种离散型的数与形的结合
 *               1
 *             1  1
 *           1  2  1
 *          1  3  3  1
 *         1  4  6  4  1
 *        1  5 10 10  5  1
 * @author: JandMin
 * @create: 2019-06-26 12:02
 **/
public class YangHuiTriangle {
    /**
     * 方案一循环次数
     */
    private static int count1;
    /**
     * 方案二循环次数
     */
    private static int count2;
    public static void main(String[] args) {
        int n = 10;
        long start = System.currentTimeMillis();
        int[][] triangle1 = getTriangle1(n);
        System.out.println("方案一:count1 = " + count1 + " 耗时 " + (System.currentTimeMillis() - start) + " ms");
        print(triangle1);
        start = System.currentTimeMillis();
        int[][] triangle2 = getTriangle2(n);
        System.out.println("方案二:count2 = " + count2 + " 耗时 " + (System.currentTimeMillis() - start) + " ms");
        print(triangle2);
    }
    /**
     * @Description: 方案一:获取前n行杨辉三角
     * @Date: 2019/6/26
     * @param n
     * @return: int[][]
     */
    private static int[][] getTriangle1(int n) {
        if (n <= 0){
            return null;
        }
        int[][] array = new int[n][n];
        for(int i=0; i<n; i++){
            int[] row = getRow(i+1);
            array[i] = row;
        }
        return array;
    }

    /**
     * @Description: 获取第n行数组
     * @Date: 2019/6/26
     * @param n
     * @return: int[]
     */
    private static int[] getRow(int n) {
        if (n <= 0){
            return new int[0];
        }
        int[] array = new int[n];
        array[0] = 1;
        array[n-1] = 1;
        if(n <= 2){
            return array;
        }
        for (int i=1; i<n-1; i++){
            count1++;
            int[] before = getRow(n-1);
            array[i] = before[i] + before[i-1];
        }
        return array;
    }
    /**
     * @Description: 方案二:获取前n行杨辉三角
     * @Date: 2019/6/26
     * @param n
     * @return: int[][]
     */
    private static int[][] getTriangle2(int n) {
        if (n <= 0){
            return null;
        }
        int[][] array = new int[n][];
        int[] before = null;
        for(int i=0; i<n; i++){
            int[] row = getRow(i+1,before);
            before = row;
            array[i] = row;
        }
        return array;
    }
    /**
     * @Description: 获取第n行数组
     * @Date: 2019/6/26
     * @param n
     * @param before  前一行数组
     * @return: int[]
     */
    private static int[] getRow(int n,int[] before) {
        int[] array = new int[n];
        array[0] = 1;
        array[n-1] = 1;
        if(n <= 2){
            return array;
        }
        for (int i=1; i<n-1; i++){
            count2++;
            array[i] = before[i] + before[i-1];
        }
        return array;
    }
    /**
     * @Description: 打印杨辉三角
     * @Date: 2019/6/26
     * @param triangle
     * @return: void
     */
    private static void print(int[][] triangle){
        int n = triangle.length;
        for(int i=0; i<n; i++){
            for (int s=n-i; s>0; s--){
                System.out.print(" ");
            }
            int[] row = triangle[i];
            int len = row.length;
            for(int j=0; j<len; j++){
                System.out.print(row[j]);
                if(row[j]<10) {
                    System.out.print("   ");
                } else if(row[j]<100){
                    System.out.print("  ");
                } else {
                    System.out.print(" ");
                }
            }
            System.out.println();
        }
    }
}

打印结果:

猜你喜欢

转载自blog.csdn.net/ItRuler/article/details/93760490