【ROSALIND】【練Python,學(xué)生信】67 無(wú)根二叉樹(shù)的數(shù)目

如果第一次閱讀本系列文檔請(qǐng)先移步閱讀【ROSALIND】【練Python,學(xué)生信】00 寫(xiě)在前面 ?謝謝配合~

題目:
無(wú)根二叉樹(shù)的數(shù)目(Counting Unrooted Binary Trees)
?
Given: A positive integer n (n≤1000).
所給:一個(gè)不大于1000的整數(shù)n。
Return: The value of b(n) modulo 1,000,000.
需得:b(n)的值,對(duì)1,000,000取模。
?
測(cè)試數(shù)據(jù)
5
測(cè)試輸出
15
?
背景
? ? ? ? 在55 創(chuàng)建字符表中我們知道,從一棵樹(shù)上刪除一條邊,就會(huì)產(chǎn)生兩棵獨(dú)立的樹(shù),每棵樹(shù)都是原始樹(shù)的子集,可以用S∣Sc表示這種樹(shù)的分裂。我們也可以用這種分裂集合來(lái)唯一的表示一棵無(wú)根二叉樹(shù)。
? ? ? ??在本題中,我們想要知道在有n個(gè)葉子結(jié)點(diǎn)的情況下,一共有多少課不同的無(wú)根二叉樹(shù)。為了解決這個(gè)問(wèn)題,我們首先要定義何為“相同”的無(wú)根二叉樹(shù),具有相同分裂的兩棵樹(shù)即為“相同的無(wú)根二叉樹(shù)”,反之,如果兩棵樹(shù)的分裂是不同的,則被認(rèn)為是“不同的無(wú)根二叉樹(shù)”。
? ? ? ??在本題中,我們定義b(n)表示具有n個(gè)葉子結(jié)點(diǎn)的的不同無(wú)根二叉樹(shù)的總數(shù)。
?
思路
? ? ? ??對(duì)于生物專(zhuān)業(yè)的同學(xué),本題題目可能相當(dāng)難懂。總結(jié)來(lái)說(shuō),題目會(huì)給我們?nèi)~子結(jié)點(diǎn)的數(shù)量,我們來(lái)回答具有這些葉子的無(wú)根二叉樹(shù)一共有多少棵。接下來(lái)我們會(huì)將解題步驟分解,并繪圖來(lái)幫助理解。
(1)理解一棵有n個(gè)葉子結(jié)點(diǎn)的無(wú)根二叉樹(shù)肯定有2n-3條邊;
? ? ? ??由無(wú)根二叉樹(shù)的特點(diǎn)可知,一個(gè)結(jié)點(diǎn)要么度為3(內(nèi)結(jié)點(diǎn)),要么度為1(葉子節(jié)點(diǎn))。
有3個(gè)葉子結(jié)點(diǎn)的樹(shù):

? ? ? ??有4個(gè)葉子結(jié)點(diǎn)的樹(shù),其中一種情況為:

? ? ? ??有5個(gè)葉子結(jié)點(diǎn)的樹(shù),其中一種情況為:

? ? ? ??葉子結(jié)點(diǎn)更多的情況也可以以此類(lèi)推,邊滿足2n-3。
(2)?把一個(gè)新結(jié)點(diǎn)通過(guò)一條邊連在現(xiàn)有的邊上,我們就可以得到一棵新的無(wú)根二叉樹(shù);除了這種辦法以外,沒(méi)有其他連接新結(jié)點(diǎn)的方法。
? ? ? ??舉個(gè)例子,我們向有3個(gè)葉子結(jié)點(diǎn)的那棵樹(shù)添加一個(gè)新結(jié)點(diǎn),操作過(guò)程如下:

? ? ? ??畫(huà)圖可知,這是唯一的添加新結(jié)點(diǎn)方法,其他方法無(wú)法滿足無(wú)根二叉樹(shù)的定義。
(3)可能具有n片葉子的樹(shù)的數(shù)量是具有n-1片葉子的樹(shù)的數(shù)量的2(n-1)-3倍;
? ? ? ??在進(jìn)化樹(shù)中,每一片葉子結(jié)點(diǎn)都代表一個(gè)不同的種屬,因此在每個(gè)邊上添加新結(jié)點(diǎn)都會(huì)產(chǎn)生一個(gè)不同的進(jìn)化樹(shù)。由于有n-1個(gè)葉子結(jié)點(diǎn)的樹(shù)有2(n-1)-3條邊,因此每棵樹(shù)添加一個(gè)結(jié)點(diǎn)都可以產(chǎn)生2(n-1)-3個(gè)新的樹(shù),再乘上n-1個(gè)葉子結(jié)點(diǎn)的樹(shù)的數(shù)目,就得到了有n片葉子的樹(shù)的數(shù)量。
? ? ? ??經(jīng)過(guò)以上三步可以看到我們得到了一個(gè)遞歸,有n片葉子的樹(shù)的數(shù)量由有n-1個(gè)葉子結(jié)點(diǎn)的樹(shù)的數(shù)目決定,即b(n)=[2(n-1)-3]*b(n-1)。
? ? ? ??因?yàn)橹挥幸豢糜?片葉子的樹(shù),所以最終的公式為T(mén)(n)=1?3?…(2n?5)=(2n?5)!!
? ? ? ??想明白這個(gè)過(guò)程,代碼就非常簡(jiǎn)單啦,甚至都不需要有注釋~
?
代碼