使用递归树的大 O 表示法分析

Posted

技术标签:

【中文标题】使用递归树的大 O 表示法分析【英文标题】:Big O Notation analysis using recursion tree 【发布时间】:2015-06-14 10:08:57 【问题描述】:

一个问题来自:http://qpleple.com/divide-and-conquer/ 算法比较

您是 Facebook 的产品经理,您团队中的三位工程师提出了这三种算法来检测 n=10 亿 Facebook 帐户列表中的虚假 Facebook 帐户。

Rakesh 解决问题的方法是将问题分成五个大小为一半的子问题,递归地解决每个子问题,然后在线性时间内组合解决方案。

Chris 通过递归求解两个大小为 n-1 的子问题,然后在恒定时间内组合解决方案来解决大小为 n 的问题。

Matus 解决大小为 n 的问题,方法是将它们分成 9 个大小为 n/3 的子问题,递归地解决每个子问题,然后在 O(n²) 时间组合解决方案

所以通过使用主定理,我发现:

Rakesh 算法的运行时间为O(n<sup>log₂(5)</sup>) Matus 算法的运行时间为O(n<sup>2log(n)</sup>)

绘制递归树并使用:

Rasket 的算法有:

#levels = log₂(n) #of 节点 k = 5k k 级每个节点的开销 = n/2k

但是无论我怎么努力,我都无法得到等于O(n<sup>log₂(5)</sup>)的总和,Matus的算法也是如此。

另外,有没有办法用主定理解决克里斯算法的运行时间?

【问题讨论】:

【参考方案1】:

申请

#levels = log₂(n) #of 节点 k = 5k k 级每个节点的开销 = n/2k

你得到(使用geometric formula)

T(n) = Σk=0,...,log₂(n) 5k ⋅ n/2k = n ⋅ Σk=0,...,log₂(n) (5/2)k = n ⋅ (1 - (5/2)log₂(n)+1) / (1 - 5/2) = (n - n ⋅ (5/2) ⋅ 5log2(n) / 2log2(n)) / (1 - 5/2) = (n - n ⋅ (5/2) ⋅ 5log₂(n) / n) / (1 - 5/2) = (n - (5/2) ⋅ 5log₂(n)) / (1 - 5/2) = ((5/2) ⋅ 5log₂(n) - n) / (5/2 - 1) = ((5/2) ⋅ 5log₂(n) - n) / (3/2) = (5/3) ⋅ 5log2(n) - (2/3) ⋅ n ∈ Θ(5log2(n))

现在你只需要显示5<sup>log₂(n)</sup> = n<sup>log₂(5)</sup>,大约一行就可以完成。

我为 Chris 得到的递归方程是

T(n) = 2⋅T(n-1) + O(1)

这不能通过使用主定理来解决,但是您可以将其扩展为一个总和并解决它:

T(n) = 2⋅T(n-1) + Θ(1) = 2⋅(2⋅T(n-2)+ Θ(1)) + Θ(1) = 2²⋅T(n-2) + 2⋅Θ(1) + Θ(1) ... = 2n⋅T(1) + 2n-1⋅Θ(1) + ... + 2⋅Θ(1) + Θ(1) = 2n+1⋅Θ(1) - 1 ∈ Θ(2n)

这适用于T(1) ∈ Θ(1)

【讨论】:

以上是关于使用递归树的大 O 表示法分析的主要内容,如果未能解决你的问题,请参考以下文章

线段树的基础递归的使用

[数据结构] 树森林的遍历

LeetCode根据二叉树创建字符串&&二叉树的构建以及遍历(递归)

打印树的每个叶子路径而不递归

二叉树的Morris遍历算法

无递归、无堆栈且不改变树的树遍历