1. 程式人生 > >Leetcode 96. 不同的二叉搜索樹

Leetcode 96. 不同的二叉搜索樹

clas nat arch += [] bin public 結點 href

題目鏈接

https://leetcode.com/problems/unique-binary-search-trees/description/

題目描述

給定一個整數 n,求以 1 ... n 為節點組成的二叉搜索樹有多少種?

示例:

輸入: 3
輸出: 5
解釋:
給定 n = 3, 一共有 5 種不同結構的二叉搜索樹:

   1         3     3      2      1
    \       /     /      / \           3     2     1      1   3      2
    /     /       \                    2     1         2                 3

題解

首先定義一個函數G[n]:表示1...n構成的二叉搜索樹的個數。1...n序列中的每個點都可以當做根節點,該節點左邊的序列構成左子樹,右邊的序列構成右子樹。比如給定一個序列[1,2,3,4,5,6,7],我們選取節點3為根結點。左子樹為[1,2]構成,可以使用G[2]來表示;右子樹[4,5,6,7]可以使用G[4]來表示(由G[n]的定義可知,[4,5,6,7]和[1,2,3,4]構成的子樹個數相同)。我們使用f(3, 7)來表示序列長度為7,根結點為3時構成的二叉搜索樹的個數,則f(3,7) = G[2] * G[4];我們可以推導出f(i, n) = G[i-1] * G[n - i].
由以上分析可知:

G[n] = G[0] * G[n-1] + G[1] * G[n - 2].....G[n-1] * G[0];

分別選取每一個數作為根結點。由上式可知,要計算出G[n],需要先計算出G[0],G[1]...,運用動態規劃的思想求解。

具體分析:
https://leetcode.com/problems/unique-binary-search-trees/discuss/31666/DP-Solution-in-6-lines-with-explanation.-F(i-n)-G(i-1)-*-G(n-i)

代碼

class Solution {
    public int numTrees(int n) {
        int[] G = new int[n + 1];
        G[0] = G[1] = 1;
        for (int i = 2; i <= n; i++) {
            for (int j = 1; j <= i; j++) {
                G[i] += G[j - 1] * G[i - j];
            }
        }
        return G[n];
    }
}

Leetcode 96. 不同的二叉搜索樹