杨辉三角,是二项式系数在三角形中的一种几何排列,在中国南宋数学家杨辉1261年所著的《详解九章算法》一书中出现。在欧洲,帕斯卡(1623—-1662)在1654年发现这一规律,所以这个表又叫做帕斯卡三角形。帕斯卡的发现比杨辉要迟393年,比贾宪迟600年。
一、杨辉三角的性质
我们从这张杨辉三角示意图上发现,杨辉三角的每行行首与每行结尾的数都为1。而且,每个数等于其左上及其右上二数的和。这样我们发现,杨辉三角左右对称。
那么我们就可以通过这些基本概念把这个杨辉三角同我们所说的组合数即二项式系数联系在一起:
我们发现,第i行的第j个数,我们可以用CjiCij来表示从ii个元素中选取jj个元素的组合数。(注意,这里的第i行是从0计数)并且,由于对称性,我们可以发现,杨辉三角中第n行的第m个数恒等于本行的第n-m+1个数。与二项式系数知识点进行结合,我们会发现(1+x)n(1+x)n展开后,各次数的系数正好对应第nn行的每一项。
二、杨辉三角代码实现的递推公式
在很多题目中,我们常常需要用打表的形式先处理出杨辉三角矩阵,然后再以此为基础进行程序求解。那么我们打表的时候如果手存表格的话,不仅浪费考试时间,而且保证不了空间范围和正确性,这个时候需要我们使用递推的手段用程序处理出表格。
根据杨辉三角的性质,推出以下的递推公式:
C[i][j]=C[i−1][j]+C[i−1][j−1];
三、实现方式
3.1 使用数组的方式
根据上面的性质,如果我们要打印一个11行的杨辉三角形,我们可以将整个排列看做是一个n行,0-n列的矩阵,再结合上面的性质8,我们将这个矩阵用一个二维数组来实现,如下图:
完整代码:
package com.example.demo;
/**
* @author Biyu
* @projectName demo
* @className: YangHui
* @description //TODO
* @date: 2023-01-22 23:28
*/
public class YangHui {
public static void main(String[] args) {
yangHui(10);
}
private static void yangHui(int row) {
//定义row行,但暂时每行的列数先不定义
int[][] values = new int[row][];
for (int i = 0; i < values.length; i++) {
//行0有1列,行1有2列,....,行n有n+1列
values[i] = new int[i + 1];
for (int j = 0; j < values[i].length; j++) {
//根据性质1,每行的首尾都为:1
if (j == 0 || j == values[i].length - 1) {
values[i][j] = 1;
} else if (i > 1) {
//根据性质8,除首尾外的其它数字 = 上方数 + 上方左侧的数
values[i][j] = values[i - 1][j] + values[i - 1][j - 1];
}
}
}
print(values);
}
private static void print(int[][] values) {
for (int i = 0; i < values.length; i++) {
for (int j = 0; j < values[i].length; j++) {
System.out.printf("%-4d", values[i][j]);
}
System.out.println();
}
}
}
数组的方式比较好理解,但需要创建二维数组,效率较低,接下来我们看一下不需要数组的写法。
3.2不使用数组的方式
算法说明
根据递推公式:C[i][j]=C[i−1][j]+C[i−1][j−1];
第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。
我们将其表示为C(i , j)的组合数,那么就有以下算法:
1、例如:i=3、j=2的位置上,值为C(3,2),即(3*2)/(1*2)=3/1 * 2/2 = 3
2、例如:i=5、j=3的位置上,值为C(5,3),即(5*4*3)/(1*2*3)= 5/1 * 4/2 * 3/3 = 5 * 2 * 1 = 10
3、例如:i=7、j=4的位置上,值为C(7,4),即(7*6*5*4)/(1*2*3*4) = 7/1 * 6/2 * 5/3 * 4/4 = 35
代码实现
package com.example.demo;
/**
* @author Biyu
* @projectName demo
* @className: YangHui
* @description //TODO
* @date: 2023-01-22 23:28
*/
public class YangHui {
public static void main(String[] args) {
//yangHui(10);
yangHui2(10);
}
private static void yangHui2(int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
//计算每列的值
int value = 1;
for (int k = 0; k < j; k++) {
value = value * (i - k) / (k + 1);
}
System.out.printf("%-4d", value);
}
System.out.println();
}
}
private static void print(int[][] values) {
for (int i = 0; i < values.length; i++) {
for (int j = 0; j < values[i].length; j++) {
System.out.printf("%-4d", values[i][j]);
}
System.out.println();
}
}
}