算法-动态规划-子问题分析案例[level2]

平衡二叉树的个数

子问题分析

step1 数学建模

原始问题中,要求f(n)的平衡二叉树个数.
举个例子,设n = 5,设
g ( n ) = 二 叉 搜 索 树 个 数 g(n) = 二叉搜索树个数 g(n)=
f ( n , i ) 为 当 r o o t 为 i 时 的 二 叉 搜 索 树 个 数 f(n,i) 为 当root为i时的二叉搜索树个数 f(n,i)rooti
例如:当n = 5时,f(n,2) 为
在这里插入图片描述
显然的:
g ( n ) = ∑ i = 1 n ( f ( n , i ) ) g(n) = \sum_{i=1}^n(f(n,i)) g(n)=i=1n(f(n,i))
例如
g ( 5 ) = f ( 5 , 1 ) + f ( 5 , 2 ) + f ( 5 , 3 ) + f ( 5 , 4 ) + f ( 5 , 5 ) g(5) = f(5,1)+f(5,2)+f(5,3)+f(5,4)+f(5,5) g(5)=f(5,1)+f(5,2)+f(5,3)+f(5,4)+f(5,5)

step2 子问题分析

这道题的重复子问题是
g ( 1 , 2 , 3 ) = g ( 3 ) = g ( 2 , 3 , 4 ) = g ( 3 , 4 , 5 ) . . . g({1,2,3}) = g(3) = g({2,3,4}) = g({3,4,5})... g(1,2,3)=g(3)=g(2,3,4)=g(3,4,5)...
数学不好无法给出证明
所以,如图
在这里插入图片描述
我们可以得出
f ( 5 , 2 ) = g ( 1 ) ∗ g ( 3 ) f(5,2) = g(1)*g(3) f(5,2)=g(1)g(3)
也可以推测其他
f ( 5 , 3 ) = g ( 2 ) ∗ g ( 2 ) f(5,3) = g(2)*g(2) f(5,3)=g(2)g(2)
从而我们使用数学归纳法可以得到
f ( n , i ) = g ( i − 1 ) ∗ g ( n − i ) f(n,i) = g(i - 1)*g(n - i) f(n,i)=g(i1)g(ni)
然后,我们可以获得g(n)的完整表达式
g ( n ) = ∑ i = 1 n g ( n − i ) ∗ g ( i − 1 ) g(n) = \sum_{ i = 1}^ng(n-i)*g(i-1) g(n)=i=1ng(ni)g(i1)

step3 表达式的使用

现在这么使用这个表达式呢?
首先确定的是,这是一个递推式
则有以下步骤(使用lua比较好表达)

求取g(i)
local i = 2:n do
	--求g(i)
end
求每个g(i)值
local arr = []
function _g(i):
	for j = 1,i do
		--此时n = i
		arr[i] += arr[i - j]*arr[j - 1] -- 递推表达式求和
	end
end

完整的c++代码
class Solution {
public:

    int numTrees(int n) {
        vector<int> arr(n+4,0);
        arr[0] = 1;//空树
        arr[1] = 1;//一个树
        int sum = 0;
        for(int i = 2;i<=n;i++){
            // n = i;
            //求g(i)
            //g(i) = f(i,1)+f(i,2)+f(i,3)+...+f(i,i)

            //local gi = 0;
            //local j=1:i do
            //    gi+= {f(i,j) = arr[j - 1]*arr[i - j]}
            //end
            for(int j = 1;j<=i;j++){
                arr[i] += arr[j - 1]*arr[ i - j];
            }
        }
        return arr[n];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值