Creo que se me ocurrió algo que debería funcionar de manera general y eficiente si se garantiza que no tendrá duplicados * (sin embargo, debe ser extensible a cualquier número de agujeros y cualquier rango de enteros).
La idea detrás de este método es como la clasificación rápida, en la que encontramos un pivote y una partición a su alrededor, luego recurrimos en los lados con un agujero. Para ver qué lados tienen el agujero, encontramos los números más bajos y más altos, y los comparamos con el pivote y el número de valores en ese lado. Digamos que el pivote es 17 y el número mínimo es 11. Si no hay agujeros, debería haber 6 números (11, 12, 13, 14, 15, 16, 17). Si hay 5, sabemos que hay un agujero en ese lado y podemos recurrir solo en ese lado para encontrarlo. Tengo problemas para explicarlo más claramente que eso, así que tomemos un ejemplo.
15 21 10 13 18 16 22 23 24 20 17 11 25 12 14
Pivote:
10 13 11 12 14 |15| 21 18 16 22 23 24 20 17 25
15 es el pivote, indicado por tuberías ( ||
). Hay 5 números en el lado izquierdo del pivote, como debería haber (15 - 10), y 9 en el derecho, donde debería haber 10 (25 - 15). Entonces recurrimos en el lado derecho; notaremos que el límite anterior era 15 en caso de que el hoyo sea adyacente (16).
[15] 18 16 17 20 |21| 22 23 24 25
Ahora hay 4 números en el lado izquierdo, pero debería haber 5 (21 - 16). Entonces repetimos allí, y nuevamente notaremos el límite anterior (entre paréntesis).
[15] 16 17 |18| 20 [21]
El lado izquierdo tiene los 2 números correctos (18 - 16), pero el derecho tiene 1 en lugar de 2 (20 - 18). Dependiendo de nuestras condiciones finales, podríamos comparar el número 1 con los dos lados (18, 20) y ver que 19 falta o se repite una vez más:
[18] |20| [21]
El lado izquierdo tiene un tamaño de cero, con un espacio entre el pivote (20) y el límite anterior (18), por lo que 19 es el agujero.
*: Si hay duplicados, probablemente podría usar un conjunto de hash para eliminarlos en el tiempo O (N), manteniendo el método general O (N), pero eso podría llevar más tiempo que usar algún otro método.