2009-09-07 12 views
7

Esta pregunta surgió de la discusión en los comentarios de this answer.¿Cómo selecciono todos los elementos en una lista que están fuera de servicio?

Primero, digamos que es bastante difícil definir lo que está fuera de servicio. Tomando el ejemplo que dio Pavel Shved, en la lista [1,5,10,2,3,4,5,6,7,8,9,10,11] podemos ver "claramente" que 5 y 10 (índices 1) y 2) están fuera de servicio. Pero un algoritmo ingenuo que simplemente verifique algún tipo de lista ordenada invariante no los señalaría.

  • comprobación a[i-1]<=a[i] for all 0<i<=N produciría el elemento en el índice 3 (que es 2);

  • comprobando a[j]<=a[i] for all 0<=i<=N and 0<=j<=i arrojaría todos los elementos en los índices 3 a 12;

Mi pregunta es: ¿se puede pensar en un algoritmo para resolver este problema que produce la "respuesta correcta" (es decir, los índices 1 y 2)? Si es así, ¿bajo qué tiempo y complejidad de memoria se ejecutaría?

+0

+1 por tomar esta pregunta interesante de la pregunta original que apuntó a una pregunta completamente nueva –

Respuesta

10

Probablemente el mejor enfoque para esto sería encontrar primero el longest increasing subsequence y luego considerar que todos los elementos que no forman parte de esa secuencia están fuera de servicio. El algoritmo provisto en la página vinculada se ejecuta en el tiempo O(n log n) y usa el espacio O(n) (además del de la propia lista).

Tal enfoque sería sin duda producir la respuesta correcta para su caso de ejemplo, ya que la más larga subsecuencia creciente sería la secuencia del 1 al 11 sin incluir el precio de 5 y 10.

+0

Eso funciona en mi primer ejemplo, pero mira este: [1, 10, 2, 3, 4, 6, 5]. 10 y 6 están fuera de servicio, pero 1 y 5 no ... Cuanto más pienso en ello, más parece mi pregunta un punto discutible, porque no puedo definir lo que está fuera de servicio, como señala Botz3000. –

+0

¡Oh, espera! ¡No revisé el enlace porque creía saber qué significaba la subsecuencia de mayor duración! Luego leo esto "Esta subsecuencia no es necesariamente contigua". Ahora, creo que esa puede ser la solución. –

+1

Tenga en cuenta que con [1, 2, 3, 4, 6, 5] lo que significa "fuera de servicio" es ambiguo: el 6 podría estar fuera de servicio, O el 5 podría considerarse fuera de servicio, ya que mover uno un solo lugar a la izquierda oa la derecha pondría esa porción de la lista "en orden".En otras palabras, podría decir "el 5 es demasiado correcto" o "el 6 está demasiado lejos" y ambos serían esencialmente equivalentes en términos de "grado de desorden". – Amber

1

Cómo debe conocer el algoritmo que le elementos considerar fuera de servicio?

Si la regla es "list [i + 1] siempre debe ser list [i] + 1", entonces sería fácil, por supuesto, memorizar que después de 1, el siguiente elemento debería ser 2, seleccionar aquellos en el medio y así sucesivamente. Pero necesita una regla precisa para que el algoritmo determine qué elementos se deben considerar "fuera de orden".

0

Como dijo Dav, longest increasing subsequence es probablemente lo mejor que puede hacer.

esto está fuera de mi cabeza, por lo que puede (probablemente no lo es: P) corregir: El obvio límite inferior para este problema es O (n) ya que al menos tiene que leer cada número una vez . Pero supongamos que hay un algoritmo que se ejecutó en O (n) tiempo. Luego puede simplemente insertar los elementos fuera de servicio en orden en tiempo lineal, pero el mejor algoritmo de comparación tiene un límite inferior de O (nLogn) por lo que es una contradicción. (de lo contrario, hay métodos de ordenación sin comparación como clasificación por cubo o raíz que usan mucha memoria o explotan el tamaño de los números que se ordenan ...)

+0

Correcto. Se requiere el factor de N para procesar cada elemento en la lista (una necesidad), y se requiere el factor de log N para determinar a dónde pertenece ese elemento. Por lo tanto, cualquier algoritmo que garantice un resultado ordenado tendrá un límite inferior de O (N log N). – Amber

Cuestiones relacionadas