#big-o
#big-o
Вопрос:
Я изучаю Big O и застрял на проблеме.
Проблема —
int sample_function (int x) {
if (x<1){
return x;}
int y = x/2;
return sample_function (y) sample_function (x-y);
}
Каким будет big O, если мы вызовем 2 рекурсивных вызова (n / 2)?
Я знаю, что большой O разделяющей рекурсивной функции (n / 2) равен O (log (n)), но не уверен в этой проблеме.
Комментарии:
1. Обратите внимание, что это не вопрос о C или C . Речь идет о временной сложности этого алгоритма, которая не зависит от того, на каком языке вы его реализуете.
Ответ №1:
Решение рекуррентного соотношения
T(n) = T(ceiling(n/2)) T(floor(n/2)) O(1)
является
T(n) = O(n).
Это может быть доказано индукцией по n.
Индуктивный базис прост. Что касается шага индукции, пусть c будет положительной константой, такой, что T(ceiling(n / 2)) и T(floor(n / 2)) ограничены сверху c * ceiling(n / 2) и c * floor(n / 2) соответственно. Таким образом, T(n) ограничено сверху c * (потолок (n / 2) пол (n / 2) = c * n .
Ответ №2:
Деление целого числа x
2
на reach 0
занимает примерно log2(x)
несколько шагов. Каждый шаг удваивает количество вызовов функций. Например:
8
4 4
2 2 2 2
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
В общем, это sum( 2^k ), k = 0 ...log2(x) = O(x)
.
Для 0
и отрицательные значения, которые вы возвращаете при первом вызове, это O(1)
.
PS: Можно утверждать, что функция на самом деле O(1)
. Компилятор может заменить его на:
int sample_function (int x) {
if (x < 1) return x;
else return 0;
}
Ответ №3:
T(n) = 2 * T(n / 2) O(1) = 4 * T(n / 4) 2 * O(1) = 8 * T(n / 8) 4 * O(1) = ... = n * O(1) (n / 2) * O(1)
Итак, это O (n) .