leetcode — unique-binary-search-trees

/**
 * Source : https://oj.leetcode.com/problems/unique-binary-search-trees/
 *
 *
 * Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
 *
 * For example,
 * 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
 *
 *
 */
public class UniqueBinarySearchTree {


    /**
     * 求出给定n的所有唯一的二叉搜索树
     * 二叉搜索树:
     * 如果左子树不为空,则左子树的节点值要小于根节点的值,如果右节点不为空,则右子树节点的值大于根节点的值
     *
     * 找规律
     * 设n的唯一二叉搜索树个数为f(n)
     * n = 0, f(0) = 1
     * n = 1, f(1) = 1
     * n = 2, f(2) = 2
     * n = 3, f(3) = 5
     * .....
     *
     * 讨论n = 3的情况
     * 当根节点为1,左子树必须为空,则总数取决于右子树的个数,f(0)*f(n-1)=f(0)*f(2)=2
     * 当根节点为2,左子树为1,右子树为3,在总数为f(1)*(n-2)=f(1)*(1)=1
     * 当根节点为3,左子树为空,可能有f(0)*f(2),左子树为1,可能有f(1)*f(1),左子树为2,可能有f(2)*f(0)=2,总共有2+1+2=5
     *
     * 所以:
     * f(0) = 1
     * f(n) = f(0)*f(n-1) + f(1)f(n-2) + f(2)*f(n-3) + ... + f(n-3)f(2) + f(n-2)*f(1) + f(n-1)f(0);
     *
     * 注意:因为要计算f(n),所以数组长度应该为n+1,因为要保存0-n之间的结果
     *
     *
     * @param n
     * @return
     */
    public int uniqueTreeCount (int n) {
        if (n == 0) {
            return 1;
        }
        int[] dp = new int[n+1];
        dp[0] = 1;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < i; j++) {
                dp[i] += dp[j] * dp[i-j-1];
            }
        }

        return dp[n];
    }

    public static void main(String[] args) {
        UniqueBinarySearchTree uniqueBinarySearchTree = new UniqueBinarySearchTree();
        System.out.println(uniqueBinarySearchTree.uniqueTreeCount(0));
        System.out.println(uniqueBinarySearchTree.uniqueTreeCount(1));
        System.out.println(uniqueBinarySearchTree.uniqueTreeCount(2));
        System.out.println(uniqueBinarySearchTree.uniqueTreeCount(3));
    }

}
posted @ 2017-11-05 19:35  lacker  阅读(118)  评论(0编辑  收藏  举报