El algoritmo tortuga + liebre es asintóticamente óptimo tanto en términos de complejidad temporal como de espacio auxiliar. No puedes hacerlo significativamente mejor que eso.
También hay una solución diferente que todavía usa el tiempo O (duración de la lista) y la memoria O (1). El truco es utilizar la profundización iterativa. La solución consistirá en múltiples fases, numeradas a partir de 0. En la fase [matemática] k [/ matemática], use dos punteros P y Q de la siguiente manera:
- Inicialice P al comienzo de la lista.
- Mueva P por [matemática] 2 ^ k [/ matemática] pasos. Si en algún momento llega al final, responda que la lista es finita.
- Inicializar Q a P.
- Mueve Q por [matemática] 2 ^ k [/ matemática] pasos. Si en algún momento llega al final, responda que la lista es finita. Si después de un paso Q = P, responda que la lista tiene un ciclo.
- Si llegaste a este paso, la fase actual finaliza. Incremente [math] k [/ math] y comience desde el principio.
Si la lista es finita, el algoritmo termina tan pronto como [math] 2 ^ k [/ math] excede su longitud. Si la lista tiene un ciclo, el algoritmo termina tan pronto como [math] 2 ^ k [/ math] excede tanto la duración del período anterior como la duración del período. En cualquier caso, se puede mostrar que la complejidad del tiempo total es lineal en la longitud de la lista. (Comente si esto no es obvio).
- ¿Cuáles son los mejores proyectos de estructura de datos para los estudiantes?
- ¿Qué partes de c ++ se deben conocer para aprender algoritmos para ioi?
- Cómo agregar dos elementos de matriz usando punteros
- ¿Cuáles son las debilidades del descenso de gradiente?
- ¿Existe algún vínculo en los algoritmos o técnicas de estructura de datos más utilizados en la programación competitiva?