递归和master公式
递归的本质是系统帮我们进行了压栈,栈的名字叫做系统栈。但系统栈的空间十分有限,因此在工程上我们需要把递归改写成用内存中的栈来模拟系统压栈,以此来实现非递归。
master公式又叫主定理,是一种估算递归时间复杂度的公式。但有个前提条件:只有是子问题规模相同的递归才能使用。
T(N) = a * T(N / b)+ O(N ^ c), a 、b 、c都是常数。
a是调用的子问题的次数
b是问题被分为多少个子问题的个数
c是调用之外的时间复杂度
如果logba < c, 复杂度为: (N ^ c)。
如果logba > c, 复杂度为: (N ^ logba)。
如果logba == c, 复杂度为: (N ^ c * logN)。
补充:T(N) = a * T(N / b)+ O(N * logN),时间复杂度是O(N * (logN) ^ 2)。
题目如下:利用分治法求一个数组中的最大值。
code分析
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#define u unsigned
#define ll long long
#define sc scanf
#define pr printf
#define fr(i, j, n) for (int i = j; i < n; i++)
#define N 10
int max(int *a, int l, int r) {
if (l >= r) {
return a[l];
}
int mid = l + ((r - l) >> 1);
int lMax = max(a, l, mid);
int rMax = max(a, mid + 1, r);
return lMax > rMax? lMax: rMax;
}
int main(int argc, char* argv[])
{
int a[N] = {0};
srand(time(0));
fr (i, 0, N) {
sc("%d", a + i);
}
pr("%d", max(a, 0, N - 1));
return 0;
}
那么这个递归可以用master公式吗?很明显是可以的因为,每个子问题都是相同规模的。
那么T(N) = T(N * 1 / 2) + T(N * 1 / 2) + O(1),那么化简一下T(N) = 2 * T(N / 2) + O(N ^ 0)。那么a = 2,b = 2, c = 0。
那么logba > c,所以时间复杂度是O(N ^ logba),因为a = 2, b = 2,所以logba = 1,所以时间复杂度是O(N ^ 1) = O(N)。
那么如果我每次把问题分成求左边2 / 3的最大值和求右边2 / 3的最大值的话,那么还能用master公式吗,也可以因为子问题的规模是相同的,那么时间复杂度就是T(N) = T(N * 2 / 3) + T(N * 2 / 3) + O(1) = 2 * T(N / (3 / 2)) + O(N ^ 0)。那么a = 2, b = 3 / 2, 因为master是除法,所以是倒数关系。
那么如果我每次都要在返回之前都要打印一下我的数组,那时间复杂度是多少呢?
那么很明显是T(N) = 2 * T(N / 2) + O(N ^ 1), 因为除了调用的时间复杂度是O(N),所以是O(N ^ 1)。那么a = 2, b = 2, c = 1。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具