Вопрос 1
void f(int n) {
if (n<1000000)
return 0;
for (int i=0; i<(n*n); i++)
return f(n-1);
}
for
l oop вообще не зацикливается, потому что содержимое является оператором return
, поэтому у вас есть максимум одна l oop итерация. Это означает, что вы можете упростить этот код до:
void f(int n) {
if (n<=0)
return 0;
return f(n-1);
}
(упрощено в отношении анализа O (n))
Здесь вы понимаете, почему это O(n)
потому что он ведет обратный отсчет, пока не достигнет условия остановки рекурсии. Тот факт, что существует проверка «высокого» значения для n<100000
, не имеет значения, когда вы вызываете его с чем-то вроде f(5*10^300);
Вопрос 2
int f(int n) {
for (int i=1; i< (n/2); i++)
for(double j =0; j <100; j+= (100.0/n)
doSomething (n/2); //doSomething(m) has time complexity of O(m)
return 0;
}
Что касается анализа O(n)
, вы можете упростить некоторые строки:
for (int i=1; i< (n/2); i++)
Это можно упростить до:
for (int i=1; i<n; i++)
Следовательно, это O(n)
, как вы уже определили .
for(double j =0; j <100; j+= (100.0/n)
Это можно упростить как:
for(double j =0; j <1; j+= (1.0/n) (divided by 100)
for(double j =0; j <n; j+= 1.0) (multiplied by n)
И снова простой O(n)
l oop.
doSomething (n/2);
То есть определение O(n)
утверждение.
Итак, всего у вас есть O(n)*O(n)*O(n)
, что составляет O(n^3)
.
Вопрос 3
int f(n) {
if (n<1) return;
g(n-1);
}
void g(n) {
f(n/2)
doOne(); // doOne has time complexity O(1)
}
Не уверен, как вы получили O(n*log(n))
здесь, потому что проверяется не каждое значение n
. На самом деле вы начинаете с n
и выполняете следующие шаги: n/2
, n/4
, n/8
, n/16
, n/32
, n/64
, n/128
, ... и в какой-то момент вы достигли прекратить условие if (n<1)
. Это просто O(log(n))
l oop.