楊輝三角的5個特性,一個比一個牛皮!

小傅哥發表於2023-01-13

作者:小傅哥
部落格:https://bugstack.cn

沉澱、分享、成長,讓自己和他人都能有所收穫!?

一、前言

楊輝三角的歷史

楊輝三角按照楊輝於1261年所編寫的《詳解九章演算法》一書,裡面有一張圖片,介紹此種演算法來自於另外一個數學家賈憲所編寫的《釋鎖算書》一書,但這本書早已失傳無從考證。但可以肯定的是這一圖形的發現我國不遲於1200年左右。在歐洲,這圖形稱為"巴斯加(Pascal)三角"。因為一般都認為這是巴斯加在1654年發明的。其實在巴斯加之前已經有許多人普及過,最早是德國人阿匹納斯(Pertrus APianus),他曾經把這個圖形刻在1527年著的一本算術書封面上。但無論如何,楊輝三角的發現,在我國比在歐洲至少要早300年光景。

此外楊輝三角原來的名字也不是三角,而是叫做開方作法本源,後來也有人稱為乘法求廉圖。因為這些名稱實在太古奧了些,所以後來簡稱為“三角”。

在小傅哥學習楊輝三角的過程中,找到了一本大數學家華羅庚的PDF《從楊輝三角談起 - 華羅庚》。—— 這些數學真的非常重要,每每對映到程式中都是一段把for迴圈最佳化成演算法的體現,提高執行效率。

二、楊輝三角構造

在開始分享楊輝三角的特性和程式碼實現前,我們先來了解下楊輝三角的結構構造。

楊輝三角的5個特性,一個比一個牛皮!

楊輝三角的結構和規律非常簡單,除去每次兩邊的1,中間的數字都是上面兩個數字的和。如圖示意的三角區域。但也就是如此簡單的結構,卻有著諸多的數學邏輯體現。包括我們計算的二項式、N選X的種數還有斐波那契數列等,都可以在楊輝三角中體現出來。接下來我們就來看看這些特性。

三、楊輝三角特性

為了方便學習楊輝三角的數學邏輯特性,我們把它按左對齊方式進行排列。

[1]
[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]
[1,7,21,35,35,21,7,1]
[1,8,28,56,70,56,28,8,1]

接下來我們就以這組楊輝三角數列,來展示它的數學邏輯特性。關於楊輝三角的Java程式碼放已到下文中,讀者可以查閱。

1. 二項式展開

大家在上學階段一定學習過二項式展開,例如:(x+y)^2 = x^2 + 2xy + y^2 其實這個展開的數學邏輯在楊輝三角中可以非常好的展示出來。

楊輝三角的5個特性,一個比一個牛皮!
  • 任意一個二項式展開後的數字乘積,都可以對映到楊輝三角對應的中的數字。
  • 二項式展開公式是用來計算給定二項式的指數冪的展開式的公式。對於給定的二項式 (x + y)n,二項式展開公式為:(x + y)^n = x^n + nx^{n-1}y + n(n-1)x^{n-2}y^2 + ... + y^n 這個公式也正好符合楊輝三角的數字值。

2. 組合數

組合數是數學中定義的一種數學概念,用於計算有多少種選擇可以從一組物品中選擇出若干的物品。比如你早上有5種水果可以吃,但你吃不了那麼多,讓你5種水果中選2個,看看有多少種選擇。透過使用公式 c(n,k) = n!/k!(n-k)! 可以計算出,5選2有10種選擇。

那麼這樣一個計算也是可以體現在楊輝三角中的。

楊輝三角的5個特性,一個比一個牛皮!
  • 5選2,在楊輝三角中可以找到第5行的第2列,結果是10。按照這個規律,5選3=10、5選4=5

3. 斐波那契數列

斐波那契數列出現在印度數學中,與梵文韻律有關。在梵語詩歌傳統中,人們對列舉所有持續時間為 2 單位的長 (L) 音節與 1 單位持續時間的短 (S) 音節並列的模式很感興趣。關於更多斐波那契更多知識可以閱讀小傅哥的:《程式設計師數學:斐波那契》—— 為什麼不能用斐波那契雜湊,做資料庫路由演算法?

斐波那契數列可以由遞迴關係定義:F0 = 0,F1 = 1,Fn = Fn-1 + Fn-2

F0 F1 F2 F3 F4 F5 F6 F7 F8 F9
0 1 1 2 3 5 8 13 21 34

而這樣一個有規律的斐波那契數列在楊輝三角中也是有所體現的。

楊輝三角的5個特性,一個比一個牛皮!
  • 把斜對角的數字做加和,會得到一組斐波那契數列;1、1、2、3、5、8、13、15、33

4. 次方數

在楊輝三角中還有一個非常有意思的特性,就是有2的次方和11次方數。

2次方

楊輝三角的5個特性,一個比一個牛皮!
- 楊輝三角每一行的數字加和,正好的2的0次方、1次方..n次方

11次方

楊輝三角的5個特性,一個比一個牛皮!
  • 另外一個是11的次冪,例如11的2次冪的結果正好是121這一排數字的組合。如果是11的5次冪,中間有連續的10,則是把後一位向前一位進位一下。

5. 平方數

楊輝三角的5個特性,一個比一個牛皮!
  • 在楊輝三角中還有一個平方數的規律體現。比如3的平方正好是右側3+6的結果。4的平方是右側6+10的結果。

四、楊輝三角實現

接下來我們實現下楊輝三角;

public HashMap<Integer, Integer> pascalTriangle(int lineNumber) {
    HashMap<Integer, Integer> currentLine = new HashMap<>();
    currentLine.put(0, 1);
    int currentLineSize = lineNumber + 1;
    for (int numberIdx = 1; numberIdx < currentLineSize; numberIdx += 1) {
        /*
         * https://github.com/trekhleb/javascript-algorithms/blob/master/src/algorithms/math/pascal-triangle/pascalTriangle.js
         * 第i行號中的第 -th 個條目lineNumber是 Binomial CoefficientC(lineNumber, i)並且所有行都以 value 開頭1。這個思路是C(lineNumber, i)使用C(lineNumber, i-1). 它可以O(1)使用以下方法及時計算:
         * C(lineNumber, i)   = lineNumber! / ((lineNumber - i)! * i!)
         * C(lineNumber, i - 1) = lineNumber! / ((lineNumber - i + 1)! * (i - 1)!)
         *
         * 從以上兩個表示式我們可以推匯出下面的表示式:C(lineNumber, i) = C(lineNumber, i - 1) * (lineNumber - i + 1) / i
         * 所以C(lineNumber, i)可以從C(lineNumber, i - 1)時間上算出來O(1)
         */
        currentLine.put(numberIdx, ((null == currentLine.get(numberIdx - 1) ? 0 : currentLine.get(numberIdx - 1)) * (lineNumber - numberIdx + 1)) / numberIdx);
    }
    return currentLine;
}

單元測試

@Test
public void test_PascalTriangle() {
    PascalTriangle pascalTriangle = new PascalTriangle();
    for (int i = 0; i <= 10; i++) {
        HashMap<Integer, Integer> currentLineMap = pascalTriangle.pascalTriangle(i);
        System.out.println(JSON.toJSONString(currentLineMap.values()));
    }
}

[1]
[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]
[1,7,21,35,35,21,7,1]
[1,8,28,56,70,56,28,8,1]
[1,9,36,84,126,126,84,36,9,1]
[1,10,45,120,210,252,210,120,45,10,1]
  • 這樣我們可以得到一組楊輝三角數列了。

五、常見面試題

  • 楊輝三角有哪些用途?
  • 用程式碼實現下楊輝三角。—— 在LeetCode中也有這樣的題目

相關文章