LintCode 不同的二叉查找树
2015-12-08 22:03
316 查看
不同的二叉查找树
给出 n,问由 1…n 为节点组成的不同的二叉查找树有多少种?给出n = 3,有5种不同形态的二叉查找树:
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
Solution:
对于该问题我们可以使用动态规划来求解。。对于动态规划问题我们需要确定问题的状态和状态转换方程。
首先我们来确定问题的状态:给定i(1≤i≤n)i ( 1 \le i \le n), 由1...i1 ... i组成的不同的二叉查找树有f(i)f(i)种。
因此,
当 i=1i = 1 时 , 只有一个节点,f(1)=1f(1) = 1.
当 i=2i = 2 时,存在两个节点1, 2。当以2作为根节点是只有1中,以1作为根节点时也只有1种,因此总共有2种。
当i=3i = 3 时,存在三个节点1,2,3。我们来进行详细的叙述。
以3根节点时。其它的节点1,2只能在左子树。及
3 / {1, 2}, 此时就转换成了{1,2}有多少种二叉树。因此,3为根节点时有2中不同的二叉树
以2为根节点时,节点3只能在右子树,节点1只能在左子树。及
2 / \ {1} {3}, 由于左子树只有一个节点因此只有1种,同样右子树也只有1中。因此2为根节点有1x1=1种。
以1为根节点时,节点{2,3}只能在右子树。及
1 \ {2,3}, 此时就变成{2,3}有多少种二叉树{2,3}=f(2)。因此1为根节点有2种。
因此有f(3) = 2 + 1 + 2 = 5种。
分析到这里状态转换方程应该很容易写出来了吧?!
对于ii, 以k(1≤k≤i)k (1 \le k \le i)作为根节点, 左子树的节点为1,...,k−1{1, ..., k-1}共有k−1k-1个节点,右子树的节点为k+1,...,i{k+1, ..., i}共有i−ki-k个节点。因此,状态装换方程为
f(i)=∑ik=1f(k−1)×f(i−k)f(i) = \sum_{k=1}^{i}f(k-1)\times f(i-k)
注意:边界条件f(0)=1
上述等式还可以继续进行优化,这里不再详细叙述。详见代码.
public class Solution { /** * @paramn n: An integer * @return: An integer */ public int numTrees(int n) { // write your code here int [] res = new int[n+1]; res[0] = 1; for (int i = 1; i <= n; ++i) { for (int j = i-1; j >= i/2; --j) { if (i%2==1 && j == i/2) res[i] += res[j] * res[i-j-1]; else res[i] += res[j] * res[i-j-1]*2; } } return res ; } }
相关文章推荐
- java中Inputstream,outputstream(字节输入输出流)
- scp文件到远端服务器提示 command not found
- 面试时如何做自我介绍
- dubbo.xsd文件 找不到解决方法
- 字符串学习
- BZOJ 2821: 作诗(Poetize)( 分块 )
- jquery学习(二)-DOM操作
- 《软件需求十步走》阅读计划第三篇
- 【Shell】read用法
- 自定义datastage阶段
- c# 账号密码加密, 写入读取ini文件
- Leetcode187: H-Index
- Collections
- android中正确保存view的状态
- 在Visual Studio中开启OpenMP
- VIM+qmake编译示例程序HelloQt出错问题的解决(文件名一定要使用.cpp,否则就会默认使用gcc编译,当然通不过)
- 杭电5532 Almost Sorted Array
- 关联容器(二):mutiset
- Linux-MongoDB安装说明
- 【学习】Javascript设计模式——反模式