zoukankan      html  css  js  c++  java
  • 96. Unique Binary Search Trees (Tree; DP)

    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
    
     
     法I:后序遍历。同Unique Binary Search Trees II,只是现在要返回的是数量,而无需将子树的所有情况放在数组中返回。
    class Solution {
    public:
        int numTrees(int n) {
            if(n==0) return 0;
            else return postOrderTraverse(1,n);
        }
        
        int postOrderTraverse(int start, int end)
        {
            if(start == end){ //递归结束条件:碰到叶子节点(没有子节点)
                return 1;
            }
            
            int leftNum, rightNum, num=0;
            for(int i = start; i<=end; i++){ //iterate all roots
                leftNum = 0;
                rightNum = 0;
                if(i > start){ //count left tree
                    leftNum = postOrderTraverse(start, i-1); 
                }
                if(i < end){ //count right tree
                    rightNum = postOrderTraverse(i+1, end); 
                }
                
                //visit root: count number for each (leftTree, rightTree) pair
                if(leftNum==0) num+=rightNum;
                else if(rightNum==0) num+=leftNum;
                else num+=leftNum*rightNum;
            }
            return num;
        }
    };

    Result:  Time Limit Exceeded

    法II:法I超时的原因是进行了很多重复计算。比如,在1-3的子树数量和4-6子树数量是相通的,因为它们的数字跨度相同。

    解决方法是用动态规划存储每种数字跨度下的子数数量

    class Solution {
    public:
        int numTrees(int n) {
            if(n==0) return 0;
            int dp[n+1];
            dp[0] = 0; 
            dp[1] = 1;
            for(int i = 2; i <= n; i++){
                dp[i] = 0; //initialize
                for(int j = 1; j <= i; j++){ //traverse root
                    if(i-j>0 && j>1) //左、右子树都存在
                        dp[i] += dp[j-1]*dp[i-j];
                    else if(j>1) //only left tree
                        dp[i] += dp[j-1];
                    else //only right tree
                        dp[i] += dp[i-j];
                }
            }
            return dp[n];
        }
    
    };
  • 相关阅读:
    BEGIN2 序列求和
    BEGIN2 序列求和
    《算法竞赛入门经典》 习题45 IP网络(IP Networks,ACM、ICPC NEERC 2005,UVa1590)
    C#中char空值的几种表示方式
    C#中char空值的几种表示方式
    C#中() =>是什么意思
    C#中() =>是什么意思
    C# Task 暂停与取消
    C# Task 暂停与取消
    C# WinForm设置透明
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/4854388.html
Copyright © 2011-2022 走看看