Другой способ проанализировать сложность состоит в том, чтобы выяснить, сколько еще итераций добавляется, если вы удвоите n
.
for (i = 1; i <= 2*n; i++){
for(j = 1; j <= 2*n; j += i) { // note: not j++
printf("Iteration %d : %d\n", i, j);
}
}
. Это можно разбить на два цикла:
for (i = 1; i <= n; i++){
for(j = 1; j <= 2*n; j += i) { // note: not j++
printf("Iteration %d : %d\n", i, j);
}
}
for (i = n+1; i <= 2*n; i++){
for(j = 1; j <= 2*n; j += i) { // note: not j++
printf("Iteration %d : %d\n", i, j);
}
}
В первом l oop это выглядит как оригинальное l oop, но внутренний размер l oop удвоился. Итак, первый l oop выполняется вдвое дольше, чем исходный алгоритм.
Для второго l oop время выполнения равно O (n), поскольку внутренний l oop выполняет 2 итерации для каждое значение i
(исключая последнее значение i
, для которого существует 1 итерация).
Итак, если T (n) - это время выполнения вашего исходного алгоритма тогда
T (2n) = 2 × T (n) + C × n
Что эквивалентно
T (n) = 2 × T (n / 2) + C × n / 2
, который распознается как типичная сложность двоичного разделения и завоевания O (n lg n) .