刻意练习:LeetCode实战 -- 不同的二叉搜索树

背景

今天,第二期基础算法(Leetcode)刻意练习训练营 的打卡任务是“不同的二叉搜索树 II”,而LeetCode也有“不同的二叉搜索树”题目,故一起写了。


题目

  • 题号:96
  • 难度:中等
  • https://leetcode-cn.com/problems/unique-binary-search-trees/

给定一个整数 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)表示n个节点二叉排序树的个数,f(i)表示以i作为根节点的二叉排序树的个数。

因此有:G(n) = f(1) + f(2) + f(3) + ... + f(n)

i为根节点的左子树有i-1个节点,因此左子树有G(i-1)种二叉排序树

右子树有n-i个节点,因此右子树有G(n-i)种二叉排序树

从而得到:f(i) = G(i-1)*G(n-i)

最后得到:G(n) = G(0)*G(n-1) + G(1)*G(n-2) + G(2)G(n-3) + ... + G(n-1)*G(0)

G(0) = 1
G(1) = 1
G(2) = G(0)*G(1) + G(1)*G(0)
G(3) = G(0)*G(2) + G(1)*G(1) + G(2)*G(0)
......
  • 执行结果:通过
  • 执行用时:48 ms, 在所有 C# 提交中击败了 66.10% 的用户
  • 内存消耗:14.6 MB, 在所有 C# 提交中击败了 16.67% 的用户
public class Solution
{
    public int NumTrees(int n)
    {
        if (n == 0 || n == 1)
            return 1;

        int[] dp = new int[n + 1];
        dp[0] = 1;
        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];
    }
}

往期活动

LSGO软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!

  • Python基础刻意练习活动即将开启,你参加吗?
  • Task01:变量、运算符与数据类型
  • Task02:条件与循环
  • Task03:列表与元组
  • Task04:字符串与序列
  • Task05:函数与Lambda表达式
  • Task06:字典与集合
  • Task07:文件与文件系统
  • Task08:异常处理
  • Task09:else 与 with 语句
  • Task10:类与对象
  • Task11:魔法方法
  • Task12:模块

我是 终身学习者“老马”,一个长期践行“结伴式学习”理念的 中年大叔

我崇尚分享,渴望成长,于2010年创立了“LSGO软件技术团队”,并加入了国内著名的开源组织“Datawhale”,也是“Dre@mtech”、“智能机器人研究中心”和“大数据与哲学社会科学实验室”的一员。

愿我们一起学习,一起进步,相互陪伴,共同成长。

后台回复「搜搜搜」,随机获取电子资源!
欢迎关注,请扫描二维码:

你可能感兴趣的:(C#学习,数据结构与算法)