[英]How to measure the time-complexity (Big-O) of this algorithm?
I'm attempting to measure the big-O complexity of the following algorithm: 我试图测量以下算法的大O复杂度:
int sumSome(int[] arr){
int sum = 0;
for (int i=0; i<arr.length; i++) {
for (int j=1; j<arr.length; j = j*2) {
if (arr[i] > arr[j])
sum += arr[i];
}
}
return sum;
}
Now from my understanding, 现在从我的理解,
if (arr[i] > arr[j])
sum += arr[i];
has big O of O(1) since it's constant and nothing is happening however, the for loop that sounds it though I'm having a hard time attempting to discern its Big-O notation. O(1)有很大的O,因为它是常数并且没有任何事情发生,但是听起来它的for循环虽然我很难分辨它的Big-O表示法。 I assumed that
我认为
for (int j=1; j<arr.length; j = j*2) {
if (arr[i] > arr[j])
sum += arr[i];
}
is a linear function O(n) because j maybe 1 but it's going up in a linear fashion at O(2n) which is just O(n). 是一个线性函数O(n),因为j可能是1但它在O(2n)处以线性方式上升,这只是O(n)。 So wouldn't the entire algorithm be O(n^2)?
那么整个算法不是O(n ^ 2)吗? Apparently I didn't answer the question correctly on a MOOC exam.
显然我没有在MOOC考试中正确回答这个问题。 Thanks!
谢谢!
is a linear function O(n) because j maybe 1 but it's going up in a linear fashion at O(2n) which is just O(n).
是一个线性函数O(n),因为j可能是1但它在O(2n)处以线性方式上升,这只是O(n)。 So wouldn't the entire algorithm be O(n^2).
因此,整个算法不会是O(n ^ 2)。 Apparently I didn't answer the question correctly on a MOOC exam.
显然我没有在MOOC考试中正确回答这个问题。 Thanks!
谢谢!
It's not going up linearly, but exponentially, because you multiply j
by 2
at each iteration. 它不是线性上升,而是呈指数上升,因为你在每次迭代时将
j
乘以2
。
j = 1, 2, 4, 8, 16, 32, ..., 2^k < n
2^k < n | apply log base 2 => k < log_2 n => k = O(log n)
So the second loop is only executed O(log n)
times, making the entire sequence of code O(n log n)
. 所以第二个循环只执行
O(log n)
次,使整个代码序列为O(n log n)
。
Strictly speaking, O(n^2)
is also a correct answer, because if O(n log n)
is an upper bound, then so is O(n^2)
. 严格来说,
O(n^2)
也是一个正确的答案,因为如果O(n log n)
是一个上界,那么O(n^2)
。 Big Theta of n^2
would not be correct however, and people usually also use Big-Oh to refer to tight bounds. 然而,
n^2
大Theta不正确,人们通常也会使用Big-Oh来指代严格的界限。
The key to Big-O is looking for loops, so your key piece is here: Big-O的关键是寻找循环,所以你的关键部分在这里:
for (int i=0; i<arr.length; i++) {
for (int j=1; j<arr.length; j = j*2) {
if (arr[i] > arr[j])
sum += arr[i];
}
}
The outer loop executes N times, since it goes from 0 to N in increments of 1. 外循环执行N次,因为它以0为增量从0到N.
The inner loop executes Log N times, per outer iteration, because it does from 1 to N exponentially. 内部循环每次外部迭代执行Log N次,因为它以指数方式从1到N执行。 (The piece you missed, I suspect, is the iterator in the loop:
j = j*2
. This makes J increase exponentially, not linearly, so it'll reach N in log-base-2 time. It would be linear if it was +2
, instead of *2
) (我怀疑,你错过的那个是循环中的迭代器:
j = j*2
这使得J呈指数增长,而不是线性增长,因此它将在log-base-2时间内达到N.如果它是+2
,而不是*2
)
The if inside doesn't matter for Big-O, as it only adds a coefficient. if-inside对Big-O无关紧要,因为它只增加了一个系数。
So, just multiply the orders of the loops: N * Log N = N Log N
因此,只需乘以循环的顺序:
N * Log N = N Log N
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.