Escriba un programa (o función) que exhiba cuatro complejidades comunes de tiempo de O grande dependiendo de cómo se ejecute. En cualquier forma, toma un número entero positivo N que puede suponer que es menor que 2 31 .
Cuando el programa se ejecuta en su forma original , debe tener una complejidad constante . Es decir, la complejidad debe ser Θ (1) o, de manera equivalente, Θ (1 ^ N) .
Cuando el programa se invierte y ejecuta, debe tener una complejidad lineal . Es decir, la complejidad debe ser Θ (N) o, de manera equivalente, Θ (N ^ 1) .
(Esto tiene sentido ya queN^1
se1^N
invierte).Cuando se programa un doble , es decir, concatenado a sí mismo, y ejecutarlo debe tener exponencial complejidad, específicamente 2 N . Es decir, la complejidad debe ser Θ (2 ^ N) .
(Esto tiene sentido ya que el2
en2^N
es el doble de la1
en1^N
.)Cuando el programa se duplicó y revirtió y ejecutarlo debe tener polinomio complejidad, específicamente N 2 . Es decir, la complejidad debe ser Θ (N ^ 2) .
(Esto tiene sentido ya queN^2
se2^N
invierte).
Estos cuatro casos son los únicos que necesita manejar.
Tenga en cuenta que, para mayor precisión, estoy usando la notación theta grande (Θ) en lugar de la gran O porque los tiempos de ejecución de sus programas deben estar limitados tanto por encima como por debajo de las complejidades requeridas. De lo contrario, solo escribir una función en O (1) satisfaría los cuatro puntos. No es demasiado importante entender los matices aquí. Principalmente, si su programa está haciendo operaciones k * f (N) para alguna k constante, entonces es probable que esté en Θ (f (N)).
Ejemplo
Si el programa original fuera
ABCDE
luego ejecutarlo debería llevar un tiempo constante. Es decir, si la entrada N es 1 o 2147483647 (2 31 -1) o cualquier valor intermedio, debe terminar aproximadamente en la misma cantidad de tiempo.
La versión inversa del programa.
EDCBA
debería llevar un tiempo lineal en términos de N. Es decir, el tiempo que tarda en terminar debe ser aproximadamente proporcional a N. Por lo tanto, N = 1 toma menos tiempo y N = 2147483647 toma más.
La versión duplicada del programa.
ABCDEABCDE
debe tomar tiempo de dos-a-la N en términos de N. Es decir, el tiempo que se necesita para terminar debe ser aproximadamente proporcional a 2 N . Entonces, si N = 1 termina en aproximadamente un segundo, N = 60 tomaría más tiempo que la edad del universo para terminar. (No, no tienes que probarlo).
La versión duplicada y revertida del programa.
EDCBAEDCBA
debería tomar el tiempo al cuadrado en términos de N. Es decir, el tiempo que tarda en terminar debe ser aproximadamente proporcional a N * N. Entonces, si N = 1 termina en aproximadamente un segundo, N = 60 tardaría aproximadamente una hora en terminar.
Detalles
Debe mostrar o argumentar que sus programas se ejecutan en las complejidades que usted dice que son. Dar algunos datos de tiempo es una buena idea, pero también trate de explicar por qué teóricamente la complejidad es correcta.
Está bien si en la práctica los tiempos que toman sus programas no son perfectamente representativos de su complejidad (o incluso deterministas). por ejemplo, la entrada N + 1 a veces puede correr más rápido que N.
El entorno en el que ejecuta sus programas sí importa. Puede hacer suposiciones básicas sobre cómo los lenguajes populares nunca pierden tiempo intencionalmente en algoritmos, pero, por ejemplo, si sabe que su versión particular de Java implementa el ordenamiento de burbujas en lugar de un algoritmo de ordenamiento más rápido , entonces debe tener eso en cuenta si hace algún ordenamiento .
Para todas las complejidades aquí, supongamos que estamos hablando de los peores escenarios , no el mejor de los casos o el caso promedio.
La complejidad espacial de los programas no importa, solo la complejidad del tiempo.
Los programas pueden generar cualquier cosa. Solo importa que tomen el entero positivo N y que tengan las complejidades de tiempo correctas.
Se permiten comentarios y programas multilínea. (Puede suponer que
\r\n
revertido es\r\n
por compatibilidad con Windows).
Big O Recordatorios
De más rápido a más lento es O(1), O(N), O(N^2), O(2^N)
(orden 1, 2, 4, 3 arriba).
Los términos más lentos siempre dominan, por ejemplo O(2^N + N^2 + N) = O(2^N)
.
O(k*f(N)) = O(f(N))
para constante k. Así O(2) = O(30) = O(1)
y O(2*N) = O(0.1*N) = O(N)
.
Recuerda O(N^2) != O(N^3)
y O(2^N) != O(3^N)
.
Cuidadosamente grande O hoja de trucos.
Puntuación
Este es el código normal de golf. El programa original más corto (el de tiempo constante) en bytes gana.
n = input(); for i in xrange(n): pass
tiene una complejidad exponencial, ya que toma 2 ** k
pasos, donde k = log_2(n)
está el tamaño de entrada. Debe aclarar si este es el caso, ya que cambia drásticamente los requisitos.