題:
Unique Binary Search Trees I
Given n, how many structurally unique BST’s (binary search trees) that store values 1 … n?
Example:
Input: 3
Output: 5
Explanation:
Given n = 3, there are a total of 5 unique BST's:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
題意:數字1-n可以組成多少個不同的二叉搜索樹
思路:
開始想嘗試用類似數字全排列的回溯方法去做,但並不是每一種全排列的方式都可以組成BST,如:以2爲根節點,就只有一種BST,但全排有兩種,遂不可行。
用動態規劃的方法,分別計算左子樹和右子樹的可行個數,再相乘就是所有可能的個數。從最小的子問題依次計算,注意dp[0]=1,因爲空子樹也可以算一種BST
在下面的代碼中,第一個循環對應共有幾個數,第二個循環對應以哪個數爲根節點。
class Solution:
def numTrees(self, n: int) -> int:
dp = [0 for _ in range(n+1)]
dp[0] = 1
for i in range(1, n+1):
for j in range(i):
dp[i] += dp[j] * dp[i-1-j]
return dp[-1]
Unique Binary Search Trees II
題:
Given an integer n, generate all structurally unique BST’s (binary search trees) that store values 1 … n.
Example:
Input: 3
Output:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
題意:這次要把所有的二叉搜索樹都打印出來
思路:
這個問題的解決思路依然是從小到大,在循環中調用遞歸函數求解子問題,並記錄下來。具體是每次選取一個結點爲根,然後遞歸求解左右子樹的所有結果,然後每一個左子樹的結果和每一個右子樹的結果匹配生成一種最終結果,總共有左右子樹數量的乘積種情況,
上下兩道題的解題依據都是:當數組爲 1,2,3,4,… i,… n時,基於以下原則的BST建樹具有唯一性:
以i爲根節點的樹,其左子樹一定由[1, i-1]構成(注意是構成,該左子樹並不唯一), 其右子樹一定由[i+1, n]構成。
下面代碼中,每一個res列表中存儲的都是[start, end]數據內,以 i 爲根節點的所有樹。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def generateTrees(self, n: int) -> List[TreeNode]:
if not n:return []
res = self.helper(1, n)
return res
def helper(self, start, end):
res = []
if start > end:
res.append(None)
return res
for i in range(start, end+1):
left = self.helper(start, i-1)
right = self.helper(i+1, end)
for item1 in left:
for item2 in right:
item = TreeNode(i)
item.left = item1
item.right = item2
res.append(item)
return res