Это код O(n) или O(logn)?

Это всего лишь проверка цикла for 1/3n раз, так что, я думаю, он все еще технически линейный? Однако я действительно не понимаю, почему это не будет O (logn), потому что много раз код с временем выполнения O (logn) заканчивается проверкой около 1/3 n. Всегда ли O(logn) каждый раз делит варианты на 2?

int a = 0;
for (int i = 0; i < n; i = i+3)
    a = a+i;

person user3251142    schedule 19.03.2014    source источник
comment
Когда вы удваиваете n, удваивается ли количество повторений вашего цикла? Или он добавляет константу?   -  person hobbs    schedule 19.03.2014
comment
Ваш пример - O (n); потому что он линейный. Рассмотрим что-то вроде бинарный поиск для логарифмического алгоритма.   -  person Elliott Frisch    schedule 19.03.2014
comment
это имеет смысл, Хоббс. спасибо за разъяснение   -  person user3251142    schedule 19.03.2014
comment
Небольшая придирка, но ; после i = i + 3 является синтаксической ошибкой.   -  person ajb    schedule 19.03.2014
comment
мой плохой, не хотел это писать   -  person user3251142    schedule 19.03.2014


Ответы (4)


ваш код имеет сложность O(n), O(n)/3 == a * O(n) == O(n)

person user902383    schedule 19.03.2014

При анализе временной сложности постоянные факторы не имеют значения. Вы можете выполнить 1 000 000 операций за цикл, и это все равно будет O (n). Поскольку константа 1/3 не имеет значения, это все равно O(n). Если у вас есть n на уровне 1 000 000, то 1/3 от n будет намного больше, чем log n.

Из статьи Википедии о нотации Big-O:

Пусть k — константа. Затем:

O(kg) = O(g) if k is nonzero.
person rgettman    schedule 19.03.2014
comment
регетман, у меня один вопрос. Что, если внутри цикла for у нас будет n = n-2;, следующий за a = a+i;? Что было бы в этом случае Big-O? - person user3251142; 19.03.2014
comment
@user3251142 user3251142 Все еще O(n). Количество итераций будет около n/5 вместо n/3 (используя исходное значение n). Я предполагаю, что вы добавите фигурные скобки, чтобы n=n-2 было частью цикла. - person ajb; 19.03.2014
comment
Спросите себя, будет ли число итераций в цикле for по-прежнему пропорционально исходному значению n. - person rgettman; 19.03.2014
comment
ну, это будет (n-2*c)/3 или что-то в этом роде.. правильно? что, если вы удвоите n, время выполнения не удвоится таким же образом... не так ли? - person user3251142; 19.03.2014
comment
@user3251142 user3251142 Все эти 2*c и /3 — это операции с константами. Это все еще O (n). Способ сделать такой цикл O(log n) состоит в том, чтобы либо делить n на константу в каждом цикле, либо умножать i на константу в каждом цикле. - person rgettman; 19.03.2014
comment
как насчет того, если бы внутри цикла for у меня было это: if (n%3 == 2) n = 9;. Если бы n имел остаток 2, код закончился бы очень быстро! Не создает ли это огромную дисперсию? - person user3251142; 19.03.2014
comment
разве это не O (n) и O (9)? - person user3251142; 19.03.2014
comment
Я знаю, что ответ, вероятно, O (n), но как это может быть, если у него есть возможность так быстро завершить цикл? - person user3251142; 19.03.2014
comment
@user3251142 user3251142 Это зависит от того, какой вопрос задают. Если вопрос заключается в том, какова верхняя граница, то это по-прежнему O (n), потому что цикл может выполняться k * n раз (для некоторой константы k). Если это среднее время, ваш цикл будет постоянным в 1/3 случаев и O(n) в остальных 2/3, поэтому среднее время будет составлять 2/3 того, что было бы без if, но это все еще постоянный множитель, поэтому среднее значение по-прежнему равно O (n). Боюсь, вычисление дисперсии или стандартного отклонения выше моих сил. - person ajb; 19.03.2014

Это порядок O(n), а не O(logn). Это потому, что время работы увеличивается линейно с увеличением n

Для получения дополнительной информации взгляните на этот график, и, надеюсь, вы поймете, почему он не регистрируется https://www.cs.auckland.ac.nz/software/AlgAnim/fig/log_graph.gif

person pizzaEatingGuy    schedule 19.03.2014

Время работы O(n) (в единицах измерения сложности).

person Codor    schedule 19.03.2014