主定理的内容
《算法导论》中提到了主定理,用来分析分治方法带来的
主定理是解决递归时间复杂度的一种直接方法,适合于以下类型的递推公式
其中 为问题规模, 为递推的子问题数量, 为每个子问题的规模(假设每个子问题的规模基本一样), 为递推以外进行的计算工作量
那么问题的时间复杂度 为
- 如果 ,则
- 如果 ,则
- 如果 ,则
说明:像 这个公式就不符合上面的递归类型,不过它可以通过换元得到上面形式,这里不再赘述
具体应用
例:二分查找
假设每个子问题的规模基本一样
,所以
例:归并排序
假设每个子问题的规模基本一样
,所以
例:LeetCode 236. 二叉树的最近公共祖先
LeetCode 题解 | 236. 二叉树的最近公共祖先(经典递归 C++)
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)
return NULL;
// 可认为左右子树已经实现了函数的功能
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(root == p || root == q)
return root;
if(left == NULL)
return right;
if(right == NULL)
return left;
if(left && right) // p和q在两侧
return root;
return NULL; // 必须有返回值
}
};
假设每个子问题的规模基本一样,也就是说我们可以假设左右子树的结点数相同
,所以
例:LeetCode 105. 从前序与中序遍历序列构造二叉树
LeetCode 题解 | 105. 从前序与中序遍历序列构造二叉树(递归 C++)
主定理证明
参考证明