PHP 帕斯卡三角形(Pascal’s Triangle)

        帕斯卡三角形是二项式系数的三角形阵列。编写一个函数,以整数值N作为输入,并打印帕斯卡三角形的前N​​行。

例子:

下图显示了 N=6 的帕斯卡三角形 

使用二项式系数的帕斯卡三角形:
        每行的条目数等于行号。例如,第一行有“1 ”,第二行有“ 1 1 ”,第三行有“1 2 1 ”,等等。一行中的每个条目都是二项式系数的值。行号 line 中第 i 个条目的值为C(line, i)。可以使用以下公式计算该值。

C(line, i) = line! / ( (line-i)! * i! )

算法:

    对帕斯卡三角形的每一行(即 1 到N )运行一个循环。
        对于每一行,对该行的每个元素运行内部循环。
            使用方法中提到的公式计算元素的二项式系数。
            
下面是上述方法的实现:

<?php
// PHP implementation for
// Pascal's Triangle
 
// for details of this function

//see https://blog.csdn.net/hefeng_aspnet/article/details/139959281
function binomialCoeff($n, $k)
{
    $res = 1;
    if ($k > $n - $k)
    $k = $n - $k;
    for ($i = 0; $i < $k; ++$i)
    {
        $res *= ($n - $i);
        $res /= ($i + 1);
    }
return $res;
}
 
// Function to print first
// n lines of Pascal's 
// Triangle
function printPascal($n)
{
    // Iterate through every line and
    // print entries in it
    for ($line = 0; $line < $n; $line++)
    {
        // Every line has number of 
        // integers equal to line 
        // number
        for ($i = 0; $i <= $line; $i++)
                echo "".binomialCoeff($line, $i)." ";
                 
        echo "\n";
    }
}
 
// Driver Code
$n=7;
printPascal($n);
 
// This code is contributed by Mithun Kumar
?> 

输出:


 1 1 
 1 2 1 
 1 3 3 1 
 1 4 6 4 1 
 1 5 10 10 5 1 
 1 6 15 20 15 6 1

时间复杂度: O(N^3),其中 N 是要打印的行数
辅助空间: O(1)

使用动态规划的帕斯卡三角形:
        如果我们仔细观察三角形,我们会发现每个条目都是其上方两个值的总和。因此,使用动态规划,我们可以创建一个二维数组来存储先前生成的值。为了在一行中生成一个值,我们可以使用数组中先前存储的值。 

案例:

if line == 0 or line == i
        arr[line][i] =1
else:
        arr[line][i] = arr[line-1][i-1] + arr[line-1][i]

下面是上述方法的实现:

<?php
// PHP program for Pascal’s Triangle
// A O(n^2) time and O(n^2) extra space 
// method for Pascal's Triangle
function printPascal($n)
{
    // An auxiliary array to store 
    // generated pascal triangle values
    $arr = array(array()); 
     
    // Iterate through every line and 
    // print integer(s) in it
    for ($line = 0; $line < $n; $line++)
    {
        // Every line has number of integers 
        // equal to line number
        for ($i = 0; $i <= $line; $i++)
        {
            // First and last values in every row are 1
            if ($line == $i || $i == 0)
                $arr[$line][$i] = 1;
                 
            // Other values are sum of values just 
            // above and left of above
            else
                $arr[$line][$i] = $arr[$line - 1][$i - 1] + 
                                $arr[$line - 1][$i];
            echo $arr[$line][$i] . " ";
        }
        echo "\n";
    }
}
 
// Driver code
$n = 5;
printPascal($n);
 
// This code is contributed
// by Akanksha Rai
?> 

输出:


1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1

时间复杂度:O(N^2)
辅助空间: O(N^2)

注意:此方法可以优化为使用 O(n) 额外空间,因为我们只需要前一行的值。因此,我们可以创建一个大小为 n 的辅助数组并覆盖值。以下是另一种仅使用 O(1) 额外空间的方法。

使用二项式系数的帕斯卡三角形(空间优化):
        该方法基于使用二项式系数的方法。我们知道行号 line 中的第 i 个条目是二项式系数 C(line, i) ,并且所有行都以值 1 开头。这个想法是使用C(line, i-1)计算C(line, i ) 。它可以在 O(1) 时间内计算出来。

C(line, i) = line! / ( (line-i)! * i! )
C(line, i-1) = line! / ( (line – i + 1)! * (i-1)! )

我们可以从以上两个表达式得出以下表达式。

C(line, i) = C(line, i-1) * (line – i + 1) / i

因此,可以在 O(1) 时间内通过 C(line, i-1) 计算出 C(line, i)

以下是该方法的实现: 

<?php
// PHP program for Pascal's Triangle 
// A O(n^2) time and O(1) extra 
// space method for Pascal's Triangle 
 
// Pascal function 
function printPascal($n) 

    for($line = 1; $line <= $n; $line++) 
    { 
        $C = 1;// used to represent C(line, i) 
        for($i = 1; $i <= $line; $i++) 
        { 
            // The first value in a 
            // line is always 1 
            print($C . " "); 
            $C = $C * ($line - $i) / $i; 
        } 
        print("\n"); 
    } 

 
// Driver code 
$n = 5; 
printPascal($n);
 
// This code is contributed by mits
?> 

输出:


1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1

时间复杂度: O(n 2 )
辅助空间: O(1)

面试中可能会问到的问题变体:

1、找到如上所示的整个帕斯卡三角形。

2、在 O(n) 时间内给定行号和列号,仅找到帕斯卡三角形的一个元素。

3、在 O(n) 时间内,给定行号,找到帕斯卡三角形的特定行。

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值