Big O для 3 вложенных циклов
Другой вопрос о нотации Big O... Что такое Big O для следующего кода:
for (int i = n; i > 0; i = i / 2){
for (int j = 0; j < n; j++){
for (int k = 0; k < n; k++){
count++;
}
}
}
Мои мысли:
Поэтому, разбирая его, я думаю, что внешний цикл равен O(log2(n))
, тогда каждая из внутренних циклов O(n)
, которая приведет к O(n^2 * log2(n))
Вопрос № 1, является правильным?
Вопрос № 2:
при объединении вложенных циклов это всегда так же просто, как mulitply Big O каждого цикла?
Ответы
Ответ 1
Когда счетчики циклов не зависят друг от друга, всегда можно работать изнутри наружу.
Самый внутренний цикл всегда занимает время O (n), потому что он циклически n раз, независимо от значений j и i.
Когда выполняется второй цикл, он запускается для итераций O (n), на каждой итерации выполняется O (n) для запуска самого внутреннего цикла. Это занимает время O (n 2).
Наконец, когда выполняется внешний цикл, он выполняет O (n 2) на одну итерацию. Он также работает для итераций O (log n), так как он работает равным количеству раз, когда вам нужно разделить n на два, прежде чем вы достигнете 1. Следовательно, общая работа - это O (n 2 log п).
В общем, вы не можете просто комбинировать петли вместе, так как их границы могут зависеть друг от друга. В этом случае, однако, поскольку нет зависимости, время выполнения можно просто умножить. Надеемся, что приведенные выше рассуждения проливают некоторый свет на то, почему это так - потому что, если вы работаете изнутри, думая о том, как много работает каждая петля и сколько раз она это делает, промежутки времени в конечном итоге умножаются вместе.
Надеюсь, это поможет!
Ответ 2
- Да, это правильно: внешний цикл
logN
, остальные два - N
, для всего O(N^2*LogN)
- В простых случаях да. В более сложных случаях, когда индексы цикла начинаются с чисел, обозначенных другими индексами, вычисления более сложны.
Ответ 3
Чтобы ответить на это немного (обратите внимание: немного) более формально, скажем, T(n)
- это время (или количество операций), необходимое для завершения алгоритма. Затем для внешнего цикла T(n) = log n*T2(n)
, где T2(n)
- количество операций внутри цикла (без учета каких-либо констант). Аналогично, T2 (n) = n * T3 (n) = n * n.
Тогда воспользуемся следующей теоремой:
Если f 1 (n) = O (g 1 (n)) и f 2 (n) = O (g 2 (n)), то f 1 (n) × f 2 (n) = O (g 1 (п) × г <суб > 2суб > (п))
(источник и доказательство)
Это оставляет нас с T (n) = O (n 2 logn).
"Объединение вложенных циклов" - это просто применение этой теоремы. Проблема состоит в том, чтобы выяснить, сколько операций использует каждый цикл, который в этом случае прост.
Ответ 4
Вы можете действовать формально с помощью Sigma Notation, чтобы точно подражать вашим циклам:
![enter image description here]()