分析一:
动态规划问题
这道题目要求给定一个数n,有多少种二叉树排列方式,用来存储1到n。
刚开始拿到这题的时候,完全不知道如何下手,但考虑到二叉树的性质,对于任意以i为根节点的二叉树,它的左子树的值一定小于i,也就是[0, i - 1]区间,而右子树的值一定大于i,也就是[i + 1, n]。假设左子树有m种排列方式,而右子树有n种,则对于i为根节点的二叉树总的排列方式就是m x n。
我们使用dp[i]表示i个节点下面二叉树的排列个数,
那么dp方程为:
dp[i] = sum(dp[k] * dp[i - k -1]) 0 <= k < i
全排列的方式来处理这个过程,当这个过程
当数组为 1,2,3,…,n时,基于以下原则的构建的BST树具有唯一性: \textbf{以i为根节点的树,其左子树由[1, i-1]构成, 其右子树由[i+1, n]构成。}
定义f(i)为以[1,i]能产生的Unique Binary Search Tree的数目,则
如果数组为空,毫无疑问,只有一种BST,即空树,f(0)=1。
如果数组仅有一个元素{1},只有一种BST,单个节点,f(1)=1。
如果数组有两个元素{1,2}, 那么有如下两种可能
1 2
\ /
2 1
f(2) = f(0) * f(1) f(2)=f(0)∗f(1) , when 1 as root
+ f(1) * f(0) +f(1)∗f(0) , when 2 as root
再看一看3个元素的数组,可以发现BST的取值方式如下:
f(3) = f(0) * f(2) f(3)=f(0)∗f(2) , when 1 as root
+ f(1) * f(1) , when 2 as root
+ f(2) * f(0) , when 3 as root
class Solution {
public int numTrees(int n) {
int [] dp=new int [n+1];
dp[0] = 1;
dp[1] = 1;
for(int i=2;i<=n;i++){
//以哪个数据为根节点,i代表n,表示n的代表, 逐渐以0
for(int j=0;j<i;j++){
//j代表右边节点的个数,即是比i小的数据有j个,
// i-j-1代表左边的节点数据
//再加上根节点数据,一共则有i个数据情况
dp[i] += dp[j] * dp[i-j-1];
}
}
return dp[n];
}
}
至此,问题划归为一维动态规划。
进阶问题:
分析二
这道题目采用二分法和递归方法·解决, 1<=i<=n,
i代表root, [1,i-1] 为有节点 [i, n] 为右节点,然后左右两边又不断分治的方法解决
分而治之用于归并排序
result 保存的的就死可能的中间结果, 左右子树的可能性问题
类似于这种方法就是
代码书写流程
- 递归递归判断条件,递归的出口文件
- 对原始问题进行处理,处理左边,处理右边
- 合并两边结果
- 从宏观上把握这种情况
归并排序对算法:
分治: 从中间开始分开,数组元素个数大于两个数,就分开
merge :合并两边元素个数情况
class Solution {
public List<TreeNode> generateTrees(int n){
if(n==0) return new ArrayList<>();
return gen(1,n);
}
private List<TreeNode> gen(int start,int end){
//result 存储的不是最终的结果,存储的是中间可能结果
//比如[1,0], 那么这边的字树为0个节点,也就是空节点,如果是[1,1]这样的情况,那么这种情况就是单独一个节点的情况
//分治法从上到下面划分,结果从下面到上面开始返回,
List<TreeNode> result = new ArrayList<>();
if(start>end) {
result.add(null);
return result;
}
if(start==end)
{
result.add(new TreeNode(start));
return result;
}
for(int i=start;i<=end;i++){
List<TreeNode> left = gen(start,i-1);
List<TreeNode> right = gen(i+1,end);
for(TreeNode lnode: left){
for(TreeNode rnode:right){
TreeNode root =new TreeNode(i);
root.left = lnode;
root.right = rnode;
result.add(root);
}
}
}
return result;
}
}
}