二叉搜尋樹,又被稱為是二叉查詢樹、二叉排序樹,這種樹其左子樹所有節點的值均小於根節點的值,其右子樹所有節點的值均大於根節點的值,並且其左、右子樹均為二叉搜尋樹。方法一:動態規劃法空樹也是二叉搜尋樹。
這道題可以用動態規劃的思想去解決。由於給定的節點值為1~n,是一組從小到大順序排列的資料,其中,任意乙個值均可以作為根節點出現,記為 i,i的取值範圍為1 ~ n。當以 i 為根節點時,為了滿足搜尋樹的性質,其左子樹必定有1 ~ i-1 構成,右子樹必定由 i+1 ~ n 構成。
建立動態轉移陣列dp, dp[n] 表示由 1 ~ n構成的二叉搜尋樹的個數;記 f( i ) 為由 i 作為根節點時,其對應的二叉搜尋樹的個數,則有f(i) = dp[i-1] * dp [n-i]。
顯然有:
d p[
n]=∑
i=1n
f(i)
=∑i=
1n(d
p[i−
1]∗d
p[n−
i]
)dp[n] = \sum\limits_^nf(i) = \sum\limits_^n(dp[i-1] * dp [n-i])
dp[n]=
i=1∑
nf(
i)=i
=1∑n
(dp
[i−1
]∗dp
[n−i
])
int numtrees
(int n)
}return dp[n]
;}
複雜度:方法二:卡塔蘭數n階遞推關係求解時間複雜度: o(n^2) ( ∑i=
2n((
n+2)
(n−1
)2
)\sum\limits_^n(\frac)
i=2∑n
(2(n
+2)(
n−1)
))。空間複雜度: o(n) 。
上述問題其實相當於是卡塔蘭數。
卡塔蘭數是組合數學中乙個常在各種計數問題**現的數列。
令h(0)=1,h(1)=1,卡塔蘭數滿足遞迴式:
h(n)= h(0)*h(n-1) + h(1)*h(n-2) + … + h(n-1)h(0) (其中n>=2),這是n階遞推關係,與上面我們推導出的動態轉移方程一致。
卡塔蘭數的一般公式為 h(n
)=c2
nn(n
+1
)h(n)=\ \frac^}
h(n)=(
n+1)
c2nn
int numtrees
(int n)
return res /
(n +1)
;}
複雜度:方法三:卡塔蘭數1階遞推關係求解時間複雜度: o(n) ;
空間複雜度: o(1) 。
卡塔蘭數的n階遞推關係,還可以化簡為1階遞推關係:
h (n
)=(4
n+2)
(n+2
)h(n
−1)(
n>1)
h(0)
=1
h(n)= \frach(n-1) \quad (n>1) \quad h(0)=1
h(n)=(
n+2)
(4n+
2)h
(n−1
)(n>1)
h(0)
=1
int numtrees
(int n)
return res;
}
複雜度:時間複雜度: o(n) ;
空間複雜度: o(1) 。
96 不同的二叉搜尋樹
給定乙個整數 n,求以 1 n 為節點組成的二叉搜尋樹有多少種?示例 輸入 3 輸出 5 解釋 給定 n 3,一共有 5 種不同結構的二叉搜尋樹 1 3 3 2 1 3 2 1 1 3 2 2 1 2 3思路 這個題目實際上是乙個數學題,設整數p組成的二叉樹共有c p 種情況。當給定乙個整數n的時候...
96 不同的二叉搜尋樹
dp i 代表有 i 個結點 1.i 時候的二叉搜尋樹種數。首先就是要考慮怎麼和之前的dp連線起來,也就是說選擇有幾種。首先可以就直接把 i 這個數放在 i 1 二叉樹的根節點,二叉搜尋樹的種數就是dp i 1 如果把 i 放在左子樹,i 1是根節點,那就有dp 1 dp i 2 左子樹 右子樹 在...
96 不同的二叉搜尋樹
題目.middle tree的定義就是遞迴的,所以關於樹的演算法也多採用遞迴。但是這個遞迴的話存在子問題重複計算的問題,所以用dp更好 package main import fmt type treenode struct func printtree root treenode else fmt...