118. 楊輝三角

118. 楊輝三角

本文將會(huì)寫(xiě)如下幾個(gè)部分:

  • 何謂“楊輝三角”
  • LeetCode第118題題目部分
  • 思路分析
  • 題解

1. 何謂楊輝三角

觀察下圖:


看看這張圖,看出了什么?

我們可以直觀地觀察到幾條規(guī)律:

  1. 每一行的數(shù)字個(gè)數(shù)與其行號(hào)相等诡渴。例如诸老,第一行就一個(gè)數(shù)字懂昂,第五行有五個(gè)數(shù)字剂公。
  2. 從第二行起,每個(gè)數(shù)是它左上方和右上方數(shù)字之和。
  3. 每一行拿出來(lái)都是回文串琳骡,即,每一行都是沿中間對(duì)稱(chēng)的讼溺。整個(gè)三角形也是沿中間對(duì)稱(chēng)的楣号。

2. LeetCode第118題題目部分

給定一個(gè)非負(fù)整數(shù) numRows,生成楊輝三角的前 numRows 行怒坯。

示例動(dòng)圖

在楊輝三角中炫狱,每個(gè)數(shù)是它左上方和右上方的數(shù)的和。

示例:

輸入: 5
輸出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

來(lái)源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/pascals-triangle
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有剔猿。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán)视译,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

3. 思路分析

以輸出n階楊輝三角為例归敬。

思路1--直觀地使用觀察出來(lái)的規(guī)律

只要認(rèn)清“從第二行起酷含,每個(gè)數(shù)是它左上方和右上方數(shù)字之和”鄙早,然后照著這條規(guī)律寫(xiě)代碼即可。具體操作是:

  1. 建立一個(gè)n \times n的二維數(shù)組椅亚;
  2. 用一個(gè)二維循環(huán)往里填數(shù)字限番。在每行的首個(gè)元素和最后一個(gè)元素填上1,然后除首尾以外的元素用上面提到的規(guī)律賦值呀舔。
  3. 此題完成弥虐。

具體解釋一下上面的第2條操作:

  • 雖然為了填數(shù)字建立的二維數(shù)組每一行元素的個(gè)數(shù)都是n,但我們只需要保證不需要的元素不填充即可模擬出自己在紙上畫(huà)的楊輝三角媚赖。也就是說(shuō)霜瘪,第一行只填充一個(gè),第二行只填充兩個(gè)惧磺,第三行只填三個(gè)粥庄。依此類(lèi)推
  • 其實(shí)這是一個(gè)Brute-Force的思想。直接用編程語(yǔ)言翻譯"從第二行起豺妓,每個(gè)數(shù)是它左上方和右上方數(shù)字之和"這一條話惜互,剩下的讓計(jì)算機(jī)去跑就好了。

復(fù)雜度是O(n^2)琳拭,且用了O(n)的額外空間训堆。

思路2--純數(shù)學(xué)思路

此思想來(lái)源于科普中國(guó)上的介紹。

看圖:


數(shù)學(xué)表示法

在介紹這種思想前白嘁,各位讀者要將思想轉(zhuǎn)變?yōu)?作為首位開(kāi)始計(jì)數(shù)的思想坑鱼,即:

  1. 傳統(tǒng)意義上的首行是第0行,傳統(tǒng)意義上的第二行是第1行絮缅;
  2. 在每一行中鲁沥,第一個(gè)數(shù)字是第0個(gè),第二個(gè)數(shù)字是第1個(gè)耕魄;
  3. 依此類(lèi)推画恰。

然后從圖上可以看出,第i行中第j個(gè)數(shù)字正是C_{i}^{j}的值吸奴。

所以只需要用二項(xiàng)式系數(shù)計(jì)算即可允扇。

做完此題后,我們可以發(fā)現(xiàn)楊輝三角提示了二項(xiàng)式系數(shù)計(jì)算的一個(gè)遞歸式:C_{x}^{y} = C_{x-1}^{y-1} + C_{x-1}^{y}则奥。

思路3--針對(duì)思路1的改良

上面兩種方法其實(shí)還可以進(jìn)一步改良考润。

前面已經(jīng)說(shuō)過(guò),楊輝三角中读处,每一行都是回文串糊治,即每一行沿中線對(duì)稱(chēng)。那么是不是有一種方法罚舱,只求前半部分井辜,然后后半部分就可以自然地求出來(lái)了揖赴?

答案是有的:只需要循環(huán)前一半即可,后半部分對(duì)稱(chēng)賦值抑胎。舉例說(shuō)明:第5行(以0開(kāi)始計(jì)就是第4行)有5個(gè)元素燥滑,那么我們只需要對(duì)前三個(gè)元素進(jìn)行計(jì)算,后兩個(gè)直接利用回文串性質(zhì)賦值即可阿逃。

4. 題解

題解的順序?qū)?yīng)上面的思路順序铭拧。

思路1 (Java實(shí)現(xiàn))

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<>(); // res用于返回結(jié)果
        
        int[][] ans = new int[numRows][numRows];
        for(int i = 0; i < numRows; ++i){
            List<Integer> ls = new ArrayList<>();
            for(int j = 0; j <= i; ++j){
                if(j == i || j == 0){ ans[i][j] = 1; }
                else{
                    ans[i][j] = ans[i - 1][j - 1] + ans[i - 1][j];
                }
                ls.add(ans[i][j]);
            }
            res.add(ls);
        }

        return res;
    }
}

思路2 (Python實(shí)現(xiàn))

import math # 直接引入python中的math庫(kù),用于計(jì)算階乘

class Solution:
    def generate(self, numRows: int) -> List[List[int]]:
        res = list()
        for i in range(numRows):
            tmp = list()
            for j in range(i + 1):
                posi = math.factorial(i) // (math.factorial(j) * math.factorial(abs(i - j))) # 這里必須用雙斜線除號(hào)恃锉,否則posi會(huì)被自動(dòng)轉(zhuǎn)換為浮點(diǎn)數(shù)類(lèi)型
                tmp.append(posi)
            res.append(tmp)
        return res

思路3 (分別用Java和Python實(shí)現(xiàn))

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<>();

        for(int i = 0; i < numRows; ++i){
            Integer[] tmp = new Integer[i + 1];
            for(int h = 0; h < i + 1; ++h){ tmp[h] = 1; }
            List<Integer> ls = new ArrayList<>(Arrays.asList(tmp));
            if(i > 0){
                for(int j = 1; j < (i / 2) + 1; ++j){
                    int pos = res.get(i - 1).get(j - 1) + res.get(i - 1).get(j); // 唯一需要注意的點(diǎn)是:
                    ls.set(j, pos); // Java的ArrayList類(lèi)型不能像C++和Python那樣用中括號(hào)([ ])訪問(wèn)元素搀菩,
                    ls.set(i - j, pos); // 只能用get和set方法來(lái)做,所以有點(diǎn)不舒服
                } // 所以這種方法不是很推薦用Java去寫(xiě)
            }
            res.add(ls);            
        }

        return res;
    }
}
class Solution:
    def generate(self, numRows: int) -> List[List[int]]:
        res = list()
        for i in range(numRows):
            ls = [1 for _ in range(i + 1)]
            if i > 0:
                for j in range(1, i // 2 + 1): # Python需要注意的是要用//(雙斜線)來(lái)表示整除
                    ls[j] = res[i - 1][j - 1] + res[i - 1][j]
                    ls[i - j] = ls[j]
            res.append(ls)
        return res

參考文獻(xiàn)

  1. 簡(jiǎn)單而不平凡的楊輝三角
  2. 楊輝三角
  3. LeetCode
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末破托,一起剝皮案震驚了整個(gè)濱河市肪跋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌土砂,老刑警劉巖州既,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異萝映,居然都是意外死亡吴叶,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)序臂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚌卤,“玉大人,你說(shuō)我怎么就攤上這事奥秆⊙放恚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵构订,是天一觀的道長(zhǎng)侮叮。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鲫咽,這世上最難降的妖魔是什么签赃? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮分尸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歹嘹。我一直安慰自己箩绍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布尺上。 她就那樣靜靜地躺著材蛛,像睡著了一般圆到。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卑吭,一...
    開(kāi)封第一講書(shū)人閱讀 49,985評(píng)論 1 291
  • 那天芽淡,我揣著相機(jī)與錄音,去河邊找鬼豆赏。 笑死挣菲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掷邦。 我是一名探鬼主播白胀,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼抚岗!你這毒婦竟也來(lái)了或杠?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宣蔚,失蹤者是張志新(化名)和其女友劉穎向抢,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體胚委,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笋额,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了篷扩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兄猩。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鉴未,靈堂內(nèi)的尸體忽然破棺而出枢冤,到底是詐尸還是另有隱情,我是刑警寧澤铜秆,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布淹真,位于F島的核電站,受9級(jí)特大地震影響连茧,放射性物質(zhì)發(fā)生泄漏核蘸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一啸驯、第九天 我趴在偏房一處隱蔽的房頂上張望客扎。 院中可真熱鬧,春花似錦罚斗、人聲如沸徙鱼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)袱吆。三九已至厌衙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绞绒,已是汗流浹背婶希。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蓬衡,地道東北人喻杈。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撤蟆,于是被迫代替她去往敵國(guó)和親奕塑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350