2009-10-10 2 views
4

Мне нужно найти большое время O бега в следующем фрагменте:асимптотический анализ фрагмента кода

sum =0; 
for (int i=1; i<n; i++) { 
    for (int j=1; j< n/i; j++) { 
    sum = sum +j; 
    } 
} 

Я знаю, что внешний контур О (п), но у меня возникают проблемы, анализируя внутреннюю петлю. Я думаю, что это O (log n).

ответ

1

Как сказал Дэйв, это O (n log n), потому что внутренний цикл равен O (log n).

+0

Ничего себе, это было быстро; вопрос, на который я ответил, ушел :) – Dave

+0

s/question/answer/ – Dave

7

Давайте просто напишем это в этом псевдо-математическом стиле.

sum i <- [1..n] (sum j <- [1..n/i] 1) 

Внутренний цикл (сумма) необходимо

n/i 

итераций, что делает весь срок

sum i <- [1..n] (n/i) 

Упростить сумму в соответствии с законом распределения:

n * (sum i <- [1..n] (1/i)) 

Внутренний su m во многом аналогичен интегралу по 1/x, который является логарифмическим.

Таким образом, O(n log n) является правильным.

4

Лучшим подходом к этому является рассмотрение того, сколько шагов будет выполняться алгоритмом.

Если у вас есть n элементов, вы знаете, что внешний цикл будет работать не менее n раз. Поэтому он должен быть как минимум O (n).

Сколько раз внутренний цикл должен запускаться для каждого i? Увеличивается ли он, остается неизменным или уменьшается по мере увеличения?

Понятно, что количество шагов во внутреннем цикле будет уменьшаться по мере увеличения i, и, что более важно, оно уменьшается нелинейно. Значит, вы знаете, что это не так плохо, как O (n^2).

Таким образом, он находится где-то между O (n) и O (n^2) .... немного больше анализа того, как шаги, которые уменьшаются во внутреннем цикле, должны получить вас там. EDIT: ... Хотя похоже, что люди уже дали это :)

+0

Это отличное объяснение. – Dave

+0

На самом деле это может быть O (n^2) (или, более точно, Theta (n^2)), даже если количество шагов во внутреннем цикле уменьшается. Например, подумайте о том, где внутренний цикл - это шаги «n-i» (как, например, в алгоритме сортировки вставки). – JaakkoK

+0

Как насчет 'for i в 1..n для j в 1..i ...'? Согласно вашему объяснению, это не так плохо, как O (n²) ', потому что диапазон внутренних петель уменьшается с увеличением i, но он ** на самом деле равен ** O (n²) – Dario

Смежные вопросы