• 题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?


    题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?

    一开始的想法是直接递归构造,时间复杂度是指数上升;
    后来想法是找规律:
    先看例子:

    n = 1, 有一个元素,可以构成一个二叉搜索树,左右都没有元素,总数量 = 左子树数量 右子树数量,记为f(1) = f(0) f(0) = 1,这儿可以将f(0)初始化为1;
    n = 2, 1做根,那么左子树没有元素记为f(0),右子树有一个元素记为f(1), 2做根,左子树有一个元素,记为f(1),右子树没有元素记为f(0);
    总共:f(2) = f(0) f(1) + f(1) f(0) = 2;
    n = 3, 1做根,数量 = f(0) f(2), 2做根 数量 = f(1) f(1), 3做根, 数量 = f(2) f(0);
    总共 f(3) = f(0) f(2) + f(1) f(1) + f(2) f(0) = 5;
    可以看出f(n),依赖与f(0)到f(n-1),换句话说可以有前面的n-1项推导出第n项;
    分析关系表达式:
    记h(k)为以k为根可以生成的二叉搜索树数量;
    当以k为根时,他的左子树为[1,2 ··· k-1]构成,也就是左子树有k-1个元素构成,这个就可以记为f(k-1);
    右子树为[k+1 ··· n]构成,也就是右子树有n-k个元素构成,这个可以记为f(n-k);
    那么h(k) = f(k-1) * f(n-k); 要记得k的范围可以从1到n;
    整合以上规律可得到:有n个元素的二叉搜索树的数量;f(n) = h(1)+h(2)+···+h(n) = ∑ h(k) ,0 < k <= n;
    又因为h(k) = f(k-1) f(n-k)得到:f(n) = ∑ f(k-1) f(n-k); 0 < k <= n;
    代码:输入n,输出可以构造出的二叉搜索树的数量;
    时间复杂度O(n^3);

    private static int BSCount(int n) {
    		int[] res = new int[n+1];
    		res[0] = 1;
    		for(int i = 1; i<=n; i++) {
    			for(int k=1; k<=i; k++) {
    				res[i] += res[k-1] * res[i-k];
    //				System.out.println(i + " k:" + k +" " + res[i]);
    			}
    		}
    		return res[res.length-1];
    	}
    

      注释:第一个循环用来控制根节点肯能出现的情况。因为这是一个递归表达式,第二个循环是用来控制计算以当下值为根节点的时候,所以依赖的前面表达式的值是多少。

          比如计算以当n3的时候,需要计算一下三种情况:

              res[3]+=res[0]*res[2]  (以1为根节点时)

              res[3]+=res[1]*res[1]  (以2为根节点时)

              res[3]+=res[2]*res[0]  (以3为根节点时)

          那么,这些表达式中的res[1]和res[2]需要提前计算。这个是由第二个循环来完成的。

  • 相关阅读:
    GIT
    curl
    排序算法
    《软件设计师》考点分布
    lua第三方库
    WordPress
    go http
    Unity UI相关总结
    note
    LUA重难点解析
  • 原文地址:https://www.cnblogs.com/lyr2015/p/10147906.html
Copyright © 2020-2023  润新知