Я готовлюсь к тесту и нашел этот вопрос:
Я не могу определить сложность, я решил, что это либо O (n 2 sup>), либо O (n 3 sup>), и я склоняюсь к O (n 3 sup>).
Может кто-нибудь сказать мне, что это такое и почему?
Моя идея, что это O (n 2 sup>), заключается в том, что в цикле j
, j = i
, который дает форму треугольника, и затем петля k
переходит от i + 1
к j
, который, я думаю, является другой половиной треугольника.
public static int what(int[] arr)
{
int m = arr[0];
for (int i=0; i<arr.length; i++)
{
for (int j=i; j<arr.length;j++)
{
int s = arr[i];
for (int k=i+1; k<=j; k++)
s += arr[k];
if (s > m)
m = s;
}
}
return m;
}
Кроме того, если вы можете сказать мне, что он делает?
Я полагал, что он возвращает добавление натуральных чисел или самого большого целого числа в массиве.
Но для массивов, таких как {99, -3, 0, 1}
, возвращается 99
, что, я думаю, связано с ошибками. Если нет, то я понятия не имею, что он делает:
{99, 1} => returns 100
{-1, -2, -3} => return -1
{-1, 5, -2} => returns 5
{99, -3, 0, 1} => returns 99 ???
Вы можете продолжить методично, используя сигма-нотацию, чтобы получить порядок сложности роста:
У вас есть 3 для заявлений. Для больших n
вполне очевидно, что это O(n^3)
. i
и j
имеют O(n)
каждый, k
немного короче, но все же O(n).
Алгоритм возвращает наибольшую сумму последовательных членов. Вот почему для последнего возвращается 99, даже если у вас есть 0 и 1, у вас также есть -3, который уменьшит вашу сумму до 97.
PS: треугольная форма означает 1 + 2 + ... + n = n(n+1) / 2 = O(n^2)
artisan down
. Введение app' s строка версии как параметр объездчика лошадей кэша или отображение его в нижнем колонтитуле, пока обновление является тяжелой работой с другими решениями. (использование огибающей переменной для этого, вероятно, было бы самым чистым решением хотя),
– luchaos
31.03.2016, 11:36
Независимо от формы треугольника или нет, это всегда сложность O (N ^ 3), но, конечно, с более низкой постоянной, чем полные тройные вложенные циклы.
О (п ^ 3).
Вы вычислили любые два элемента между arr [0] и arr [arr.length - 1] , используя «i» и «j», что означает C (n, 2), что это n * (n + 1) / 2 раза расчета.
И средний шаг между каждым расчетом, выполняемым с помощью «k», составляет (0 + длина стрелки) / 2, поэтому общее время расчета составляет C (n, 2) * обр. длина / 2 = n * n * (n + 1) / 4, то есть O (n ^ 3).
Код:
for (int i=0; i<arr.length; i++) // Loop A
{
for (int j=i; j<arr.length;j++) // Loop B
{
for (int k=i+1; k<=j; k++) // Loop C
{
// ..
}
}
}
Асимптотический анализ на Big-O:
Loop A: Time = 1 + 1 + 1 + .. 1 (n times) = n
Loop B+C: Time = 1 + 2 + 3 + .. + m = m(m+1)/2
Time = SUM { m(m+1)/2 | m in (n,0] }
Time < n * (n(n+1)/2) = 1/2 n^2 * (n+1) = 1/2 n^3 + 1/2 n^2
Time ~ O(n^3)
Полные рассуждения таковы:
Пусть n
будет длиной массива.
1) Есть три вложенных цикла.
2) Самый внутренний цикл выполняет ровно j-i
итераций (k
, начиная с i+1
до j
включительно). Нет преждевременного выхода из этого цикла.
3) Средний цикл выполняет ровно n-j
итераций (j
от i
до n-1
включительно), каждая из которых включает j-i
самых внутренних итераций, всего (i-i)+(i+1-i)+(i+2-i)+... (n-1-i) = 0+1+2... + (n-1-i)
. Нет преждевременного выхода из этого цикла.
4) Самый внешний цикл выполняет ровно n
итераций (i
работает от 0
до n-1
включительно), каждая из которых включает 0+1+2+ ... (n-1-i)
внутренних итераций. Всего (0+1+2... n-1) + (0+1+2+... n-2) + (0+1+2+... n-3) + ... (0)
. Нет преждевременного выхода из этого цикла.
Теперь, как справиться с этим беспорядком? Вам нужно немного узнать о формуле Фолхабера ( http://en.wikipedia.org/wiki/Faulhaber%27s_formula ). В двух словах, он говорит, что сумма целых чисел до n
равна O(n^2)
; и сумма суммы целых чисел до n
равна O(n^3)
и т. д.
Если вы помните из исчисления, примитив X
является X^2/2
; и примитивом X^2
является X^3/3
. Каждый раз, когда степень увеличивается. Это не случайно.
Ваш код работает в O(n^3)
.
Если вы недостаточно разбираетесь в основной теории, чтобы напрямую применять анализ @ MohamedEnnahdiElIdri, почему бы просто не начать с тестирования кода?
Обратите внимание, что границы цикла зависят только от длины массива. , а не его содержание, поэтому в отношении сложности времени не имеет значения, что делает алгоритм. Вы могли бы также проанализировать временную сложность
public static long countwhat(int length) {
long count = 0;
for (int i = 0; i < length; i++) {
for (int j = i; j < length; j++) {
for (int k = i + 1; k <= j; k++) {
count++;
}
}
}
return count;
}
Глядя на это, легче ли вывести гипотезу? Если нет, просто проверьте, пропорционально ли возвращаемое значение length
в квадрате или length
в кубе ...
public static void main(String[] args) {
for (int l = 1; l <= 10000; l *= 2) {
long count = countwhat(l);
System.out.println("i=" + l + ", #iterations:" + count +
", #it/n²:" + (double) count / l / l +
", #it/n³:" + (double) count / l / l / l);
}
}
... и обратите внимание, что одно значение не приближается к какой-либо константе с ростом l
, а другое (не случайно, к той же самой константе, связанной с наибольшей степенью $ n $ в методологическом анализе).
view()->share
- то, что это только выполняется, когда представление используется - но с view()->share
it' s выполнил, неважно, что - Вы могли бы возвращать некоторый JSON в вызове API, например - который doesn' t используют представление.
– Petecoop
03.03.2016, 01:54
n
полностью в противоречии с математической идеей.
– jwg
18.05.2020, 17:28
Это требует O(n^3)
времени из-за того факта, что в трех циклах увеличиваются три различные переменные . То есть, когда один внутренний цикл закончен, это не влияет на внешний цикл. Внешний цикл выполняется столько раз, сколько он должен был работать до того, как был введен внутренний цикл.
И это проблема максимальной смежной суммы подмассивов. Самоочевиден, когда вы видите пример:
{99, 1} => returns 100
{-1, -2, -3} => return -1
{-1, 5, -2} => returns 5
{99, -3, 0, 1} => returns 99
Существует отличный алгоритм, известный как алгоритм Кадане (сделайте это для Google), который решает это за O(n)
время.
Вот так:
Initialize:
max_so_far = 0
max_ending_here = 0
Loop for each element of the array
(a) max_ending_here = max_ending_here + a[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far
Class 'App\Http\Controllers\View' not found
– Kokodoko 10.03.2019, 00:22O(n^3)
уже ясно определяется), и я также подтверждаю there' s никакие ошибки! It' s интересный отметить, что постоянный множитель перед соответствующимn^3
термин1/12
, в противоположность типичному1/2
дляO(n^2)
алгоритм, который формирует каждую возможную пару из последовательности и выполняет вычисление на паре. Т.е. третья сумма в OP' s вопрос - отi
доj
- вводит добавленное1/6
к постоянному множителю, подразумевая, что эта подпоследовательность является [в среднем 118] ' th длина последовательности. – Dan Nissenbaum 18.05.2020, 17:25