golang力扣leetcode 96. 不同的二叉搜索树

简介: golang力扣leetcode 96. 不同的二叉搜索树

96.不同的二叉搜索树

96.不同的二叉搜索树

题解

题目:给一个中序数组1~n,求能构造出多少种不同的二叉搜索数

递归

1.不同的二叉搜索树,根节点不同
2.根节点相同的树,子树根节点不同
3.当前节点子树个数=左子树个数*右子树个数

动态规划

dp[n]:n个节点存在二叉排序树的个数
f[i]:以i为根的二叉排序树的个数
dp[n]=f[1]+f[2]+...+f[n]
当i为根时,其左子树个数i-1,右子树个数n-i
f[i]=dp[i-1]*dp[n-i]
卡特兰数公式:dp[n]=dp[0]*dp[n-1]+dp[1]*dp[n-2]+...+dp[n-1]*dp[0]

代码

func numTrees(n int) int {
  mp := make(map[int]int)
  var dfs func(int) int
  dfs = func(n int) int {
    if n == 0 || n == 1 {
      return 1
    }
    if v, ok := mp[n]; ok {
      return v
    }
    cnt := 0
    for i := 1; i <= n; i++ {
      //用i作为根节点
      //左边多少子树
      leftNum := dfs(i - 1)
      //右边多少子树
      rightNum := dfs(n - i)
      //相乘就是当前节点子树个数
      cnt += leftNum * rightNum
    }
    mp[n] = cnt
    return cnt
  }
  return dfs(n)
}
func numTrees(n int) int {
  //dp[n]:n个节点存在二叉排序树的个数
  //f[i]:以i为根的二叉排序树的个数
  //dp[n]=f[1]+f[2]+...+f[n]
  //当i为根时,其左子树个数i-1,右子树个数n-i
  //f[i]=dp[i-1]*dp[n-i]
  //dp[n]=dp[0]*dp[n-1]+dp[1]*dp[n-2]+...+dp[n-1]*dp[0]
  dp := make([]int, n+1)
  dp[0] = 1
  dp[1] = 1
  for i := 2; i <= n; i++ { //dp[n],这里i=公式里的n
    f := 0
    for j := 1; j <= i; j++ { //f[1~n]
      f = dp[j-1] * dp[i-j]
      dp[i] += f //dp[n]=f[1]+f[2]+...+f[n]
    }
  }
  return dp[n]
}
目录
相关文章
|
28天前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
1月前
【LeetCode 45】701.二叉搜索树中的插入操作
【LeetCode 45】701.二叉搜索树中的插入操作
9 1
|
1月前
【LeetCode 44】235.二叉搜索树的最近公共祖先
【LeetCode 44】235.二叉搜索树的最近公共祖先
15 1
|
1月前
【LeetCode 48】108.将有序数组转换为二叉搜索树
【LeetCode 48】108.将有序数组转换为二叉搜索树
34 0
|
1月前
【LeetCode 47】669.修剪二叉搜索树
【LeetCode 47】669.修剪二叉搜索树
8 0
|
1月前
【LeetCode 46】450.删除二叉搜索树的节点
【LeetCode 46】450.删除二叉搜索树的节点
11 0
|
1月前
【LeetCode 42】501.二叉搜索树中的众数
【LeetCode 42】501.二叉搜索树中的众数
8 0
|
1月前
【LeetCode 41】530.二叉搜索树的最小绝对差
【LeetCode 41】530.二叉搜索树的最小绝对差
9 0
|
1月前
【LeetCode 40】98.验证二叉搜索树
【LeetCode 40】98.验证二叉搜索树
11 0
|
1月前
【LeetCode 39】700.二叉搜索树中的搜索
【LeetCode 39】700.二叉搜索树中的搜索
12 0