杨辉三角,又称帕斯卡三角,是我国南宋数学家杨辉在1261年所著的《详解九章算法》中首次记录的一种三角形数表,在欧洲则称为帕斯卡三角(Blaise Pascal,1653年研究)。它是一个无限对称的数字金字塔
研究规则设定:
杨辉三角构造规则
杨辉三角是一个由数字排列成的三角形数表,其构造规则非常简单:
顶端数字:第 0 行只有一个数字 1。
边界数字:从第1行开始,每一行的最左边和最右边的数字都是 1。
中间数字:除了边界外,中间的每一个数字都等于它正上方和左上方两个数字之和。
用数学公式表示:
规则设定:行 n 从 0 开始计数,列 k 也从 0 开始计数。
如果设 C(n,k) 为第 n 行第 k 列的数字(行和列都从 0 开始计数,且 n ≥),则:
C(n,k) = C(n-1, k-1) + C(n-1, k)
另外,每行首尾的数为:C(n,0) =1且 C(n,n)=1。
通过分析,我得出的的几个关键特点:
n代表第n行(n从0开始计数),k代表第k列(k从0开始计数)。
第 0 行:有1个数,1。
第 1 行:有2个数,1、1。
第 2 行:有3个数,1、2、1。
第 n 行:有n+1个数,第n+1个数的索引值是n,第n个数的索引值是n-1。
n 必须满足的条件是:n ≥ 2。因为只当行数n ≥ 2时,才存在中间元素。
k 必须满足的条件是:k ≥ 1 && k ≤ n-1,也就是说,让k定位到每一行不是首尾的数。
代码逻辑解析:
初始化:我们创建一个空数组 $triangle 来存储整个三角形。
外层循环:遍历每一行(从 0 到 $numRows - 1)。
行初始化:对于第 $i 行,我们创建一个长度为 $i + 1 的数组,并全部填充为 1。这一步巧妙地利用了杨辉三角“两端为 1”的特性,省去了单独判断首尾的代码。
内层循环:从第 2 行(索引为 2)开始,遍历该行中间的元素(索引从 1 到 $i - 1)。
状态转移:利用公式 $row[$j] = $triangle[$i - 1][$j - 1] + $triangle[$i - 1][$j] 计算当前值。这里 $triangle[$i - 1] 代表上一行。
存储:将构建好的行添加到 $triangle 数组中。
用 PHP 实现的杨辉三角算法
<?php
declare (strict_types = 1);
/**
* 生成杨辉三角
* 采用“先填充默认值 1,再计算中间值”的策略。
* @param int $numRows 需要生成的行数。
* @return array 返回一个二维数组。
*/
function generateYangHuiTriangle(int $numRows): array {
// 防御性编程:处理非正数输入
if ($numRows <= 0) {
return [];
}
$triangle = [];
for ($i = 0; $i < $numRows; $i++) {
// 首先把每一行的值全部初始化为 1。
$row = array_fill(0, $i + 1, 1);
// 计算中间值。只有当 i ≥ 2 时,才存在中间元素(索引 j ≥ 1 && j ≤ i-1)。
for ($j = 1; $j < $i; $j++) {
$row[$j] = $triangle[$i - 1][$j - 1] + $triangle[$i - 1][$j];
}
$triangle[] = $row;
}
return $triangle;
}
// print_r(generateYangHuiTriangle(5));
$rows = 5;
// 格式化输出杨辉三角
echo "<h3>杨辉三角({$rows}行)</h3>";
$triangle = generateYangHuiTriangle($rows);
foreach ($triangle as $line) {
echo str_repeat(" ", $rows - count($line));
echo implode(" ", $line) . "<br>";
}