leetcode | 95. Unique Binary Search Trees Ⅱ
阿新 • • 發佈:2018-12-16
題目
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
思路與解法
題目的意思很明確:給定輸入資料n,讓我們輸出所有的儲存1-n的二叉搜尋樹。
我們知道二叉樹由左子樹、右子樹以及一個根節點組成,二叉搜尋樹則額外滿足了左子樹上所有節點數值比根節點要小,右子樹上所有節點數之比根節點要大。所以,假設i
為根節點,則1~i-1
節點構成左子樹,i+1~n
構成右子樹。可以採用遞迴的思想,遞迴生成左子樹、右子樹,然後與根節點一同構成一顆完整的二叉搜尋樹。
程式碼實現
go語言實現如下:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func generateTrees(n int) []*TreeNode {
if n == 0 {
return []*TreeNode{}
}
return findTrees(1, n)
}
// 函式findTrees,尋找以s~t節點構成的樹,返回值為[]*TreeNode,因為這樣的樹並不止一顆
func findTrees(s int,t int) []*TreeNode {
list := make([]*TreeNode, 0)
// 當s>t,表示搜尋到某個節點只有一個孩子的情況,則給list加上nil
if s> t {
list = append(list, nil)
return list
}
// 當s==t,表示搜尋到葉子節點,則list加上葉子節點
if s==t {
list = append(list, &TreeNode{s, nil, nil})
return list
}
// 以i為根節點,分別搜尋左子樹、右子樹
for i:=s; i<=t; i++ {
leftNodes := findTrees(s, i-1)
rightNodes := findTrees(i+1, t)
// 將所有左、右子樹的組合情況,構成所有可能的二叉搜尋樹加上list中
for _, leftNode := range leftNodes {
for _, rightNode := range rightNodes {
root := &TreeNode{i, leftNode, rightNode}
list = append(list, root)
}
}
}
// 搜尋結束,返回list
return list
}
遇到的問題
- 遞迴搜尋中沒有
s>t
的判斷: 由上圖可以看出,如果不加上s>t
的判斷,則輸出資料只有一組[[2,1,3]]
,對應於題目給出的第四幅二叉樹。原因是源程式將只有一個孩子的節點給忽視掉了(當s>t
時返回的list為空),所以五組資料中只剩下了一組。 - 輸入資料為0 當輸入資料為0時,我們的輸出結果應該為空陣列,不應該是空陣列的陣列。