杨辉三角,是二项式系数在三角形中的一种几何排列,中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623----1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。
特性:
- 每个数等于它上方两数之和。
- 每行数字左右对称,由1开始逐渐变大。
- 第n行的数字有n项。
- 第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。
- 第n行的第m个数和第n-m+1个数相等 ,为组合数性质之一。
- 每个数字等于上一行的左右两个数字之和。可用此性质写出整个杨辉三角。即第n+1行的第i个数等于第n行的第i-1个数和第i个数之和,这也是组合数的性质之一。即 C(n+1,i)=C(n,i)+C(n,i-1)。
- (a+b)n的展开式中的各项系数依次对应杨辉三角的第(n+1)行中的每一项。
- 将第2n+1行第1个数,跟第2n+2行第3个数、第2n+3行第5个数……连成一线,这些数的和是第4n+1个斐波那契数;将第2n行第2个数(n>1),跟第2n-1行第4个数、第2n-2行第6个数……这些数之和是第4n-2个斐波那契数。
- 将第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();
}
}
}
打印结果: