Напишите программу (или функцию), которая демонстрирует четыре общих больших сложности времени, в зависимости от того, как она выполняется. В любой форме оно принимает положительное целое число N, которое, как вы можете предположить, меньше 2 31 .
Когда программа запускается в своем первоначальном виде, она должна иметь постоянную сложность. То есть сложность должна быть Θ (1) или, что то же самое, Θ (1 ^ N) .
Когда программа перевернута и запущена, она должна иметь линейную сложность. То есть сложность должна быть Θ (N) или, что то же самое, Θ (N ^ 1) .
(Это имеет смысл, такN^1
как1^N
наоборот.)Когда программа в два раза , т.е. сцеплены к себе, и работать она должна иметь экспоненциальную сложность, а именно 2 N . То есть сложность должна быть Θ (2 ^ N) .
(Это имеет смысл, поскольку2
в2^N
два раза больше, чем1
в1^N
.)Когда программа удвоилась и обратная и запустить его должен иметь полиномиальный сложности, в частности N 2 . То есть сложность должна быть Θ (N ^ 2) .
(Это имеет смысл, такN^2
как2^N
наоборот.)
Эти четыре случая - единственные, с которыми вам нужно разобраться.
Обратите внимание, что для точности я использую нотацию большого тета (no) вместо большого O, потому что время выполнения ваших программ должно быть ограничено как сверху, так и снизу требуемыми сложностями. В противном случае простое написание функции в O (1) удовлетворяет всем четырем точкам. Здесь не так уж важно понимать нюанс. Главным образом, если ваша программа выполняет k * f (N) операций для некоторой константы k, то это, вероятно, в Θ (f (N)).
пример
Если бы оригинальная программа была
ABCDE
затем запуск должен занять постоянное время. То есть, независимо от того, является ли вход N 1 или 2147483647 (2 31 -1), или любое другое значение между ними, оно должно завершиться примерно за то же время.
Обращенная версия программы
EDCBA
должно занимать линейное время в терминах N. То есть время, необходимое для завершения, должно быть примерно пропорционально N. Поэтому N = 1 занимает меньше всего времени, а N = 2147483647 - больше всего.
Удвоенная версия программы
ABCDEABCDE
должны принимать два-к-N раз , с точки зрения N. То есть, время, необходимое для завершения должна быть примерно пропорциональна 2 N . Таким образом, если N = 1 заканчивается примерно через секунду, N = 60 займет больше времени, чем возраст вселенной для завершения. (Нет, вам не нужно проверять это.)
Удвоенная и перевернутая версия программы
EDCBAEDCBA
должно занять время в квадрате в терминах N. То есть время, необходимое для завершения, должно быть примерно пропорционально N * N. Таким образом, если N = 1 заканчивается примерно через секунду, N = 60 потребовалось бы около часа для завершения.
подробности
Вам нужно показать или утверждать, что ваши программы работают в сложностях, о которых вы говорите. Предоставление некоторых временных данных является хорошей идеей, но также попытайтесь объяснить, почему теоретически сложность является правильной.
Хорошо, если на практике время, затрачиваемое вашими программами, не совсем отражает их сложность (или даже детерминированность). Например, вход N + 1 может иногда работать быстрее, чем N.
Среда, в которой вы запускаете свои программы, имеет значение. Вы можете сделать основные предположения о том, что популярные языки никогда не намеренно тратят время на алгоритмы, но, например, если вы знаете, что ваша конкретная версия Java реализует пузырьковую сортировку вместо более быстрого алгоритма сортировки , то вам следует принять это во внимание, если вы выполняете какую-либо сортировку ,
Для всех сложностей здесь предположим, что мы говорим о сценариях наихудшего случая , а не наилучшем или среднем случае.
Пространственная сложность программ не имеет значения, только временная сложность.
Программы могут выводить что угодно. Имеет значение только то, что они принимают положительное целое число N и имеют правильные временные сложности.
Комментарии и многострочные программы разрешены. (Вы можете предположить, что
\r\n
обратное -\r\n
для совместимости с Windows.)
Big O Напоминания
От самого быстрого до самого медленного O(1), O(N), O(N^2), O(2^N)
(порядок 1, 2, 4, 3 выше).
Более медленные условия всегда доминируют, например O(2^N + N^2 + N) = O(2^N)
.
O(k*f(N)) = O(f(N))
для постоянной к. Так O(2) = O(30) = O(1)
и O(2*N) = O(0.1*N) = O(N)
.
Помните O(N^2) != O(N^3)
и O(2^N) != O(3^N)
.
Аккуратный большой O шпаргалка.
счет
Это нормальный код гольфа. Самая короткая оригинальная программа (с постоянным временем) в байтах побеждает.
n = input(); for i in xrange(n): pass
имеет экспоненциальную сложность, потому что она принимает 2 ** k
шаги, где k = log_2(n)
находится размер ввода. Вы должны уточнить, так ли это на самом деле, поскольку это резко меняет требования.