c - 嵌套for循环的时间复杂度
问题描述
以下代码块 void function(int n) 的时间复杂度是多少。
我的尝试是最外面的循环将运行 n/2 次,而内部的两个循环将运行 2^q 次。然后我将 2^q 与 n 相等,得到 q 为 1/2(log n) 以 2 为底。乘以时间复杂度,我得到我的值 O(nlog(n)) 而答案是 O(nlog^2(n ))。
void function(int n) {
int count = 0;
for (int i=n/2; i<=n; i++)
for (int j=1; j<=n; j = 2 * j)
for (int k=1; k<=n; k = k * 2)
count++;
}
解决方案
是时候应用理解循环嵌套的黄金法则了:
如有疑问,请由内而外!
让我们从原始的循环嵌套开始:
for (int i=n/2; i<=n; i++)
for (int j=1; j<=n; j = 2 * j)
for (int k=1; k<=n; k = k * 2)
count++;
该内部循环将运行 Θ(log n) 次,因为在循环的 m 次迭代之后,我们看到 k = 2 m并且我们在 k ≥ n = 2 lg n时停止。所以让我们用这个更简单的表达式替换那个内部循环:
for (int i=n/2; i<=n; i++)
for (int j=1; j<=n; j = 2 * j)
do Theta(log n) work;
现在,看看最里面的剩余循环。使用与之前完全相同的推理,我们看到这个循环也运行了 Θ(log n) 次。由于我们进行了 Θ(log n) 迭代,每个迭代都进行 Θ(log n) 工作,我们看到这个循环可以用这个更简单的循环代替:
for (int i=n/2; i<=n; i++)
do Theta(log^2 n) work;
在这里,外循环运行了 Θ(n) 次,所以总运行时间是 Θ(n log 2 n)。
我认为,根据您在问题中所说的话,您有正确的见解,但只是忘记将对数项的两个副本相乘,一个用于两个内部循环中的每一个。
推荐阅读
- c++ - 无法读取 .blk 文件 C++ (Visual Studios)?
- c# - x => x + 1 和 x => x += 1 之间有区别吗?
- django - 如何修复“django.contrib.gis.geoip2 没有属性 GeoIP2”
- ios - 重叠的嵌套标签栏控制器
- amazon-web-services - 有没有办法让 CloudFormer (beta) 在启动配置中保留用户数据
- google-apps-script - 部分事件功能代码不起作用
- javascript - 用另一个数组过滤一个 javascript 数组
- asp-classic - 为什么某些站点不能使用服务器端脚本 (ASP) 通过 XMLHTTPREQUEST 加载,但我可以使用 javascript 加载?
- microservices - 微服务应该有多小?
- ruby-on-rails - 如何在我的视图中访问我的 Rails 辅助方法?“提供的位置为零。无法构建 URI”