Big o 为什么此代码的运行时为O(n^5)?
我被要求确定此代码的大O时间复杂性:Big o 为什么此代码的运行时为O(n^5)?,big-o,time-complexity,Big O,Time Complexity,我被要求确定此代码的大O时间复杂性: function(int n) { for (int i = 0; i < n; i++) { for (int j = i; j < i * i; j++) { if (j % i == 0) { for (int k = 0; k < j; k++) { printf("*"); }
function(int n) {
for (int i = 0; i < n; i++) {
for (int j = i; j < i * i; j++) {
if (j % i == 0) {
for (int k = 0; k < j; k++) {
printf("*");
}
}
}
}
}
函数(int n){
对于(int i=0;i
给出的答案是O(n5)。有人能解释为什么,或者如何确定这一点吗?我们是将最内层循环的工作次数相加,还是将每个循环的复杂度相乘?因此,O时间复杂度是嵌套在任意变量n中的每个循环的最大单个迭代次数的乘积 给你
function (int n) // as in O(n)
{
for(int i=0;i<n;i++) // n
{
for(int j=i;j<i*i;j++) // n ^ 2
{
if(j%i==0) // w/e
{
for(int k=0;k<j;k++) // n ^ 2
{
printf("*");
}
}
}
}
}
function(int n)//与O(n)中的一样
{
对于(inti=0;i这样分析代码的一种方法是从最里面的循环开始向外工作
for (int k=0; k<j; k++)
{
printf("*");
}
从这个角度看,运行时大约接近0.125n4,大约是n4/8。这实际上是有意义的——最内层循环的隐藏常数因子是1/2(因为1+2+3+…+i=i(i+1)/2),最外层循环的隐藏常数因子是1/4(因为13+23+…+n3=n2(n+1)2/4)换句话说,理论与实践非常吻合!在最坏情况下,该问题总时间复杂度的数学形式如下:
function(int n) {
for (int i = 0; i < n; i++) {
for (int j = i; j < i * i; j+=i) {
for (int k = 0; k < j; k++) {
printf("*");
}
}
}
}
所以复杂性是O(n^5)
编辑:在上面的回答中,我不注意如果性能
我们可以按如下方式更改您的代码:
function(int n) {
for (int i = 0; i < n; i++) {
for (int j = i; j < i * i; j+=i) {
for (int k = 0; k < j; k++) {
printf("*");
}
}
}
}
函数(int n){
对于(int i=0;i
因此,正如templatetypedef提到的,很明显,总运行时间是O(n^4)
您可以提供O(n^5)上的源代码吗答案?这是从哪里来的?他们给出了什么解释?这个问题在Narasimha Karumachi的《数据结构和算法变得简单》一书中给出。解释是最外层的循环执行n次,中间的循环执行nxn次,最内层的循环执行nxn次。然后他说总的复杂度是O^5@kpie我以为OP询问代码运行时的大O时间复杂性,因为我不确定他们会谈论什么其他数量。不过,我感兴趣的主要事情是确保我的数学是正确的。你看到任何看起来不对劲的地方吗?据我所知,我可能会离开这里(非常尊重177k和所有)但是O是最坏的情况,就像在没有考虑条件的情况下一样,函数的运行时间是有限的@kpie,而您可以通过将所有循环相乘得到运行时的保守上界,这通常不是确定函数运行时的好方法。您可以得到更精确的上界-这就是我正在尝试的g这里要做的是——通过更仔细地考虑每个循环实际做了多少工作。再一次,我非常确定数学是正确的,这就是为什么我试图了解为什么我得到的答案与OP建议的不同。让我们在聊天中继续这个问题……亲爱的@templatetypedef,这个问题的时间复杂性是O(n^5)
。您可以看到我的答案。我认为,与前面的答案一样,这忽略了if语句对时间复杂性的影响。我非常确定您有一个不严格的有效答案,而且我编写的程序以经验支持我的数学分析,这一事实让我相信我的答案是正确的。亲爱的@templatetypedef、 你说得对。谢谢你的好意。
#include <iostream>
#include <cstdint>
#include <cmath>
using namespace std;
uint64_t countWork(int n) {
uint64_t result = 0;
for (int i = 0; i < n; i++) {
for (int j = 1; j < i * i; j++) {
if (j % i == 0) {
for (int k = 0; k < j; k++) {
result++;
}
}
}
}
return result;
}
int main() {
for (int n = 100; n <= 1000; n += 100) {
cout << "Ratio of work to n^4 when n = "
<< n << " is " << countWork(n) / pow(double(n), 4.0)
<< endl;
}
}
Ratio of work to n^4 when n = 100 is 0.120871
Ratio of work to n^4 when n = 200 is 0.122926
Ratio of work to n^4 when n = 300 is 0.123615
Ratio of work to n^4 when n = 400 is 0.123961
Ratio of work to n^4 when n = 500 is 0.124168
Ratio of work to n^4 when n = 600 is 0.124307
Ratio of work to n^4 when n = 700 is 0.124406
Ratio of work to n^4 when n = 800 is 0.12448
Ratio of work to n^4 when n = 900 is 0.124537
Ratio of work to n^4 when n = 1000 is 0.124584
function(int n) {
for (int i = 0; i < n; i++) {
for (int j = i; j < i * i; j+=i) {
for (int k = 0; k < j; k++) {
printf("*");
}
}
}
}