• 【leetcode】Unique Binary Search Trees (#96)


    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example, given n = 3, there are a total of 5 unique BST's.

     

    1         3     3      2      1

               /     /      /      

         3     2     1      1   3      2

        /     /                       

       2     1         2                 3

    解析:

    修改上例的顺序如下:

    1        1        2        3        3

                /      /        /

    3       2   1    3   2        1

    /                  /           

    2             3      1              2

    可以看到,以 1 为根的树的个数,等于左子树的个数乘以右子树的个数,左子树是 0 个元素的树,右子树是 2 个元素的树。以 2 为根的树的个数,等于左子树的个数乘以右子树的个数,左子树是1个元素的树,右子树也是1个元素的树,以此类推。当数组为 1,2,3,...,n 时,基于以下原则的构建的BST树具有唯一性:以i为根节点的树,其左子树由[1,i-1]构成,其右子树由[i+1,n]构成。

    定义f(i)为以[1,i] 能产生的 UniqueBinarySearchTree 的数目,则有

    如果数组为空,毫无疑问,只有一种 BST,即空树,f(0) = 1。

    如果数组仅有一个元素 1,只有一种 BST,单个节点,f(1) = 1。

    如果数组有两个元素 1,2,那么有如下两种可能

    1            2

           /

    2    1

    f(2) =    f(0)∗f(1) ,1 为根的情况

    + f(1)∗f(0) ,2 为根的情况

    再看一看 3 个元素的数组,可以发现 BST 的取值方式如下:

    f(3) =   f(0)∗f(2) ,1 为根的情况

    + f(1)∗f(1) ,2 为根的情况

    + f(2)∗f(0) ,3 为根的情况

    所以,由此观察,可以得出f的递推公式为

    f(i) =∑f(k−1)×f(i−k)

    因此,可以利用动态规划解决此问题:

    /*Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
    
    For example,
    Given n = 3, there are a total of 5 unique BST's.
    
       1         3     3      2      1
               /     /      /       
         3     2     1      1   3      2
        /     /                        
       2     1         2                 3
    */
    //#include "stdafx.h"
    #include <iostream>
    #include <cstdio>
    #include <climits>
    #include <ctime>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cstdlib>
    #include <windows.h>
    #include <string>
    #include <cstring>
    
    using namespace std;
    class Solution {
    public:
        int numTrees(int n) {
            vector<int>f(n+1,0);
            f[0] = 1;
            f[1] = 1;
            for(int i=2; i<=n; i++){
            	for(int j=1; j<=i; j++){
            		f[i] +=f[j-1]*f[i-j];
            	}
            }
            return f[n];
        }
    };
    
    int main(){
    	Solution s;
    	cout<<s.numTrees(3)<<endl;
    	system("pause");
    	return 0;
    }
    

      

  • 相关阅读:
    hdu5754_找规律+威佐夫博弈
    codeforce645C_尺取法
    hdu4336_容斥dp
    poj3071_概率dp
    codeforces148D_推论题
    poj2151_概率dp
    hdu3853_概率dp
    POJ 1410 判断线段与矩形交点或在矩形内
    POJ 1066 Treasure Hunt 线段相交判断
    POJ 2653 Pick-up sticks 判断线段相交
  • 原文地址:https://www.cnblogs.com/dragonir/p/6189282.html
Copyright © 2020-2023  润新知