卡特蘭數是組合數學中乙個常出現在各種計數問題**現的數列。其公式為 :c(n)=c(2)*c(n-1)+c(3)*c(n-2)+...c(n-1)*c(2)。
假設n個節點存在
即有:g(n) = f(1) + f(2) + f(3) + f(4) + ... + f(n)
n為根節點,當i為根節點時,其左子樹節點個數為[1,2,3,...,i-1],右子樹節點個數為[i+1,i+2,...n],所以當i為根節點時,其左子樹節點個數為i-1個,右子樹節點為n-i,即f(i) = g(i-1)*g(n-i),
上面兩式可得:g(n) = g(0)*g(n-1)+g(1)*(n-2)+...+g(n-1)*g(0)
即:
接下來看幾個應用題:
給定乙個整數 n,求以 1 ... n 為節點組成的二叉搜尋樹有多少種?
輸入: 3
輸出: 5
解釋: 給定 n = 3, 一共有 5 種不同結構的二叉搜尋樹:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
動態規劃:
1、初始化]dp=[0,⋯,0],長度為n+1,儲存n0,⋯,n的卡特蘭數。初始化dp[0]=1,表示沒有節點, dp[1]=1,表示只有乙個節點的二叉搜尋樹的種類。
2、遍歷dp陣列,i遍歷區間[2,n+1):
3、返回dp[n]dp[n]
def generatetrees(n):
if n == 0:
return 0
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 1
for i in range(2, n + 1):
for j in range(i):
dp[i] += dp[j] * dp[i - j - 1]
return dp[-1]
給定乙個整數 n,生成所有由 1 ... n 為節點所組成的二叉搜尋樹。
輸入: 3
輸出:[ [1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]]
二叉搜尋樹, 一節點大於左子樹節點, 小於右子樹節點
所以我們節點是從1
到n
,當乙個節點為val
那麼它的左邊是<= val
,右邊是>=val
,
def generatetrees1(n):
if n == 0:
return
@functools.lru_cache(none)
def dfs(start, end):
res =
if start > end:
for val in range(start, end + 1):
for left in dfs(start, val - 1):
for right in dfs(val + 1, end):
root = treenode(val)
root.left = left
root.right = right
return res
return dfs(1, n)
參考: 卡特蘭數和二叉樹的構造
卡特蘭數 f n c2 nn c 2nn 1f n c n c f n c 2nn c2n n 1 簡要介紹含義 長度為2n的01序列,0 1各n個,要求前任意個數字中,1的數量 geq 0的數量.詳細請看大佬原文章 應用 1.入棧順序確定,求出棧順序。1表示入棧,0表示出棧,因為要先入棧才能出棧,...
不同的二叉搜尋樹
題目 力扣 解題思路 可以看注釋 class solution return helper choice,k choice表示選擇,按大小順序排列,k表示取第k個序列,從1開始計數 public string helper listchoice,int k 以某一元素開頭的序列個數,一共有n n個 ...
不同的二叉搜尋樹
leetcode演算法 演算法題 動態規劃 dp i 代表的是長度為i的序列所能構成多少個不同的二叉搜尋樹 f x,i 代表的是以x為根,長度為i所能構成的不同的二叉搜尋樹的種類 那麼dp i f 1,i f 2,i f i,i 同時f x,i 的公式也出來了1 2 3 4 x i 1 i 可以發現...