Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LeetCode 96. Unique Binary Search Trees #66

Open
Woodyiiiiiii opened this issue Jun 22, 2020 · 0 comments
Open

LeetCode 96. Unique Binary Search Trees #66

Woodyiiiiiii opened this issue Jun 22, 2020 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

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

这道题其实符合数学中某种数列的规律——卡塔兰数 Catalan Number。一开始,如果节点数n为0,那么返回1(空树也是二叉搜索树);n为1,只有根为1这一种情况,可以看做是其左子树个数乘以右子树的个数,左右子树都是空树,所以1乘1还是1;n为2,分为根为1,2这两种情况。

创建一个n+1长度的一维dp数组,dp[i]表示n为i时的二叉搜素树个数,我们可以得出以下递推式:

dp[2] = dp[0] * dp[1]   (1为根的情况,则左子树一定不存在,右子树可以有一个数字)

    + dp[1] * dp[0]   (2为根的情况,则左子树可以有一个数字,右子树一定不存在)

解释:1为根时,还有一个点2,所以是dp[0] * dp[1];2为根时,同理是dp[0] * dp[1]。

n = 3时:

dp[3] = dp[0] * dp[2]   (1为根的情况,则左子树一定不存在,右子树可以有两个数字)

    + dp[1] * dp[1]   (2为根的情况,则左右子树都可以各有一个数字)

    + dp[2] * dp[0]   (3为根的情况,则左子树可以有两个数字,右子树一定不存在)

相乘的原因是子树在根节点的基础上。最后代码如下:

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

参考资料:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant