嵌套for循环,改变变量时间复杂度

时间:2014-05-11 21:32:08

标签: algorithm time-complexity

我一直在寻找一些关于时间复杂性的帮助,并且当for循环中的变量都基于先前的for循环而变化时,无法找到太多。我在代码中编写了这个函数,并运行它以试图进一步理解,但是我只是无法把握它并将其放入公式中。也许如果有人能给我看一些关于如何可视化公式的提示,那就太棒了!这里没有进一步说明我写的功能:

    public static void function2(){
Scanner scanner = new Scanner(System.in);
System.out.println("enter a value for n: ");
int n = scanner.nextInt();
int counter = 0;
for (int i = 1; i <= (n-2); i++){
    System.out.println("Entered outer loop");
    for (int j = i+1; j<= (n-1); j++){
        System.out.println("Entered middle loop");
        for (int k = j+1; k<= n; k++){
            System.out.println("Entered inner loop");
            System.out.println("Hello World");
            counter++;
        }
    }
}
 System.out.println("Hello world printed: " + counter + " times");
}

所以我根据不同的输入大小运行了这个函数,并收集了这些结果: 如果n =(数字),则打印Hello world x次,n = 5,10x,n = 6,20x,n = 7,35x,n = 8,56x,n = 9,84x,n = 10,120x

我已经绘制了它,并且理解它是一个以指数速率增长的函数,但是我不确定具体的公式是什么。我还看到,当n = 5时,hello world以一个n-2,n-3,n-4次的模式输出,然后返回到中间循环,然后返回内部,运行n-3, n-4次,回到中间,然后回到内部运行n-4次。

如果有人可以帮助我更好地想象这一点,或者指出我正确的方向,那就太棒了!我觉得我非常接近答案。谢谢你的时间!

1 个答案:

答案 0 :(得分:1)

这是O(n ^ 3),因为时间复杂度会丢弃常数和低阶项。

如果我们不丢弃那些东西,那就是(n - 2)*(n - 1)/ 2 * n / 3。您可以通过以下方式自行推导出这个等式:

int n = 1000;
int loop1 = 0, loop2 = 0, loop3 = 0;
for (int i = 1; i <= (n-2); i++){
    loop1++;
    for (int j = i+1; j<= (n-1); j++){
        loop2++;
        for (int k = j+1; k<= n; k++){
            loop3++;
        }
    }
}
printf("%d %d %d\n", loop1, loop2, loop3);

对于n = 1000,这将打印“998 498501 166167000”。为了得到998到498501,我们乘以499.5,即(n - 1)/ 2。要从498501到166167000,我们乘以333.3333,即n / 3。而998显然是(n - 2)。把它放在一起,得到(n - 2)*(n - 1)/ 2 * n / 3。

如果你简化它,你会得到这个:

(n - 2) * (n - 1)/2 * n/3
(n - 2) * (n/2 - 1/2) * n/3
(n - 2) * (n/2 * n/3 - 1/2 * n/3)
(n - 2) * ((n^2)/6 - n/6)
(n^2)/6 * (n - 2) - n/6 * (n - 2)
n * (n^2)/6 - 2 * (n^2)/6 + n * -n/6 - 2 * -n/6
(n^3)/6 - (n^2)/3 - (n^2)/6 + n/3

(n^3)/6 - (n^2)/2 + n/3

但是,因为我们删除常量和低阶项,所以简化为O(n ^ 3)。