Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这个简单程序的运行时间-时间复杂性_Java_Algorithm_Time_Time Complexity_Big O - Fatal编程技术网

Java 这个简单程序的运行时间-时间复杂性

Java 这个简单程序的运行时间-时间复杂性,java,algorithm,time,time-complexity,big-o,Java,Algorithm,Time,Time Complexity,Big O,我试图弄清楚这个简单程序的时间复杂度是多少,但我似乎不明白什么是最好的方法 我已经为每一行并排写下了时间复杂度 1 public int fnA (int n) { 2 int sum = 0; O(1) 3 for (int i = 0; i < n; i++) { O(n) 4 int j = i; O(n) 5 i

我试图弄清楚这个简单程序的时间复杂度是多少,但我似乎不明白什么是最好的方法

我已经为每一行并排写下了时间复杂度

1    public int fnA (int n) {                   
2      int sum = 0;                    O(1)
3      for (int i = 0; i < n; i++) {   O(n)
4        int j = i;                    O(n)
5        int product = 1;              O(1)
6      
7        while (j > 1) {               O(n)
8          product ∗= j;               O(log n) 
9          j = j / 2;                  O(log n)
10       }
11       sum += product;               O(1)
12     }
13     return sum;                     O(1)
14   }

否对于每个i,都有
logn
循环运行,因此对于
n
元素,总复杂度为
nlogn

因为您知道下面的循环使用logn

while (j > 1) {              
        product ∗= j;             
       j = j / 2;                         
}

现在,对每个
i
执行此特定循环。这将执行
n次。因此它变成了
nlogn

算法的时间复杂度是
O(nlogn)

for
循环执行
N次(从
0
N

while
循环执行了
logN
次,因为您每次都将数字除以一半

由于您在
for
内部执行
,因此您正在执行
logN
操作
N次,从那里开始执行
O(NlogN)


所有剩余的运算(赋值、乘法、除法、求和)您可以假设需要O(1)

以上程序的关键是while循环,它是定义因子,其余行的复杂度不会超过O(n),并假设算术运算将在O(1)时间内运行

上面的循环的运行时间为O(log(j)),而j的变化范围为1到n,因此它的系列

-> O(log(1) + log(2) + log(3) + log(4).....log(n))
-> O(log(1*2*3*4...*n))
-> O(log(n!))

and O(log(n!)) is equal to O(n log(n))

有关上述证明,请首先参考,您可以计算所有操作。例如:

1    public int fnA (int n) {                   
2      int sum = 0;                    1
3      for (int i = 0; i < n; i++) {   
4        int j = i;                    n
5        int product = 1;              n
6      
7        while (j > 1) {               
8          product ∗= j;               ?
9          j = j / 2;                  ?
10       }
11       sum += product;               n
12     }
13     return sum;                     1
14   }
1公共整数fnA(整数n){
2整数和=0;1
3表示(int i=0;i1){
8产品∗= J
9 j=j/2?
10       }
11总和+=乘积;n
12     }
13返回金额;1
14   }
现在我们可以做计数了:它的总数是:2+3n+nlog(n)

在许多程序中,计数更为复杂,通常有一个突出的高阶项,例如:2+3n+2n2。当谈到性能时,我们真正关心的是n大的时候,因为当n小的时候,总和还是小的。当n较大时,高阶项会拖拽其余项,因此在本例中,2n2才是真正重要的项。这就是tilde近似的概念

考虑到这一点,通常可以快速确定执行频率最高的代码部分,并使用其计数来表示总体时间复杂度。在OP给出的示例中,它如下所示:

for (int i = 0; i < n; i++) {
    for (int j = i; j > 1; j /= 2)
        product *= j;
}
for(int i=0;i1;j/=2)
乘积*=j;
}

给∑log2n。通常计数涉及离散数学,我学到的一个技巧是用积分代替它并计算:∫ log2n=nlog(n)

你能详细说明你是如何得到这个答案的吗?@RandomMath:更新了答案。while循环while(j>1)不是O(n)?@RandomMath:它只是循环中的一个操作,实际上是O(1)。虽然它运行了n次,所以你可以把它看作O(n)。整个循环是while(j>1){积∗= j、 j=j/2;}正如您在问题中提到的,这完全需要logn时间。从技术上讲,甚至是产品∗= J为O(1)操作,j=j/2;这也是O(1)操作。但是,由于这些操作在特定的i。。。所以它变成了一个特定i的logn。当i从0循环到n时,因此这个logn循环被执行n次,使其nlogn。
1    public int fnA (int n) {                   
2      int sum = 0;                    1
3      for (int i = 0; i < n; i++) {   
4        int j = i;                    n
5        int product = 1;              n
6      
7        while (j > 1) {               
8          product ∗= j;               ?
9          j = j / 2;                  ?
10       }
11       sum += product;               n
12     }
13     return sum;                     1
14   }
for (int i = 0; i < n; i++) {
    for (int j = i; j > 1; j /= 2)
        product *= j;
}