Как рассчитать временную сложность следующей программы?
int[] vars = { 2, 4, 5, 6 };
int len = vars.length;
int[] result = new int[len];
for (int i = 0; i < len; i++) {
int value = 1;
for (int k = 0; k < i; k++) {
value = value * vars[k];
}
for (int j = i + 1; j < len; j++) {
value = value * vars[j];
}
result[i] = value;
}
и как это выше, как показано ниже?
for (int i = 0; i < len; i++) {
int value = 1;
for (int j = 0; j < len; j++) {
if(j != i) {
value = value * vars[j];
}
}
result[i] = value;
}
Цикл i
for
имеет временную сложность O (n), поскольку он выполняет одну итерацию для каждого элемента массива. Для каждого элемента массива вы перебираете его еще раз - половина в среднем for
циклу k
for
цикла, а половина - в цикле j
for
цикла. Каждый из них - O(n)
. Если в массиве имеется 4 элемента, число операций пропорционально n * (n - 1), но по временной сложности константы, такие как 1
, игнорируются.
Количество операций, которые будет выполнять ваш метод, пропорционально количеству элементов в нем, умноженному на себя, поэтому в целом метод O (n 2).
Для первого фрагмента:
Для второго фрагмента:
Общий подход при определении сложности - это подсчет итераций. В вашем примере у вас есть внешний цикл for с двумя вложенными в него петлями. Примечание: вместо len я напишу n. Внешний контур
for (int i = 0; i < n; i++)
итерации n
-times. Число итераций двух следующих циклов на самом деле легче подсчитывать, чем выглядит: Второй цикл повторяет i
-times и третий ni
-times. Если вы добавите их вместе, вы получите n
-many итерации во внешнем цикле.
Наконец, если внешняя петля выполняет n
итераций и внутри каждой из этих итераций код повторяется еще в n
раз, вы получаете результат n^2
итераций. В традиционной нотации теории сложности вы должны написать, что алгоритм имеет верхнюю границу n^2
или находится в O(n)
.