1. 程式人生 > >leetcode | 95. Unique Binary Search Trees Ⅱ

leetcode | 95. Unique Binary Search Trees Ⅱ

題目

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 }

遇到的問題

  1. 遞迴搜尋中沒有s>t的判斷: 在這裡插入圖片描述 由上圖可以看出,如果不加上s>t的判斷,則輸出資料只有一組[[2,1,3]],對應於題目給出的第四幅二叉樹。原因是源程式將只有一個孩子的節點給忽視掉了(當s>t時返回的list為空),所以五組資料中只剩下了一組。
  2. 輸入資料為0 在這裡插入圖片描述 當輸入資料為0時,我們的輸出結果應該為空陣列,不應該是空陣列的陣列。