Hace poco estuve en una entrevista donde me hicieron preguntas técnicas. Una era cómo calcularía qué número de una lista de longitud n-1 faltaba. La lista contenía todos los números de 1 a n, excepto en donde 1 < = i < = n. Los números no estaban en orden. Mi solución fue sumarlos todos, luego restarlos del cálculo de los números de 1 a n, agregando 1 a ny multiplicando por n/2 o (n-1)/2 según corresponda. Pero tuve la sensación de que había una mejor manera de hacerlo. ¿Cuál es la solución óptima?¿Cuál es la forma óptima de calcular qué número entero en una lista falta?
Respuesta
Su respuesta es lo suficientemente buena, en mi opinión.
Pero algunas personas, tal vez su entrevistador es uno de ellos, están preocupados por el desbordamiento y tal. En ese caso, use XOR en lugar de agregar.
Para obtener el XOR de los números enteros de 0 a n, simplemente combine XOR junto con los índices de la matriz mientras realiza el ciclo. Dado el XOR de los enteros de 0 a n, y el XOR de los elementos de la matriz, simplemente XOR los dos juntos para obtener el elemento faltante.
P.S. La suma de los enteros de 1 a n es siempre (n + 1) * n/2
¡Me gusta su truco de XOR! Sin embargo, es interesante que no necesita preocuparse por el desbordamiento para resolver el problema, siempre que sepa que su sistema conserva los bits del resultado correctos. reste la suma calculada (sobrevolada) de números de la suma (también sobrevencida) calculada mediante el método gaussiano, y, sorprendentemente, ¡obtendrá el número! El truco no funcionará si el sistema siempre verifica el desbordamiento de enteros (por ejemplo, Ada). Tampoco funcionará en flotadores, pero tampoco funciona el truco de XOR. El truco de XOR requiere un pase sobre la matriz, a menos que haya una fórmula cerrada como una para la suma. – kkm
@kkm: el método gaussiano solo evita el problema de desbordamiento si calcula (n/2) o (n + 1)/2 primero (el que sea un número entero). Si multiplica n por n + 1, pierde el bit alto y no puede recuperarlo cuando divide por 2. Pero sí, aparte de eso, hacer la suma del módulo 2^k funciona bien. – Nemo
Mientras recorre la matriz para calcular la suma, puede verificar si un número se repite.
Podrías ampliar eso, no puedo entender lo que quieres decir. – CSturgess
en su respuesta mencionó que la solución puede calcularse calculando la suma y luego restándola del total. para calcular la suma que tiene que iterar pensó en la matriz. – KItis
Sí, pero ¿qué quiere decir repetir? Los números no se repiten. – CSturgess
Su método es absolutamente correcto. Es óptimo en términos de espacio y tiempo. El desbordamiento puede ser el único problema.
Otro posible método podría ser el uso de un hashSet. Cree un hashSet inicial que tenga los valores 1-> N. Ahora, para cada número que encuentre en la lista, elimine ese valor de hashSet. Al final, el valor que permanece en hashSet es el valor que falta.
Este método es O (N) en complejidad de tiempo y espacio. Su método (salvo desbordamiento) fue O (N) en el tiempo y O (1) complejidad. El factor agregado 'n' para el espacio es el costo para eliminar el desbordamiento.
Su solución es más o menos óptimo con un cambio, como señala @Nemo a cabo la suma de los números enteros de 1 a n es siempre (n+1) * n/2
También vale la pena señalar que el enfoque es multi-hilo capaz (y podría adecuado para valores muy grandes de N), divida la matriz en partes, luego obtenga la suma de cada parte de la matriz en una secuencia, luego agregue esas sumas de parte. Depende de cómo se compara la sobrecarga de subprocesos con la adición de números en una matriz.
Si le preocupan los desbordamientos, y sus valores son siempre int32 (ya que la mayoría de los valores .Length
incluyen matrices) simplemente almacene la suma como un int64, la suma de todos los valores enteros positivos (((long)int.MaxValue) +1L) * (int.MaxValue/2) = 2305843007066210304
que aún puede caber dentro de un int64 con un .MaxValue = 9223372036854775807
.
La otra respuesta mencionada por otros es para XOR cada elemento y mantener un XOR en ejecución, pero luego tiene que encontrar una fórmula para obtener el XOR total esperado en O(1)
vez.
Lo más probable es que el entrevistador está buscando para ver si se da cuenta que hay una solución O(N)
con O(1)
memoria (que su respuesta es), en lugar de la clasificación de la matriz y siendo mucho más lento para valores muy grandes de N
.
Para mejorar aún más su solución en el código, sería utilizar un puntero para acceder a la matriz en lugar del valor del índice (que si su código es C# será una mejora razonable).
- 1. ¿Cuál es la forma óptima de calcular un código hash para un conjunto de puntos?
- 2. ¿Cuál es la forma óptima de manejar imágenes rotas?
- 3. ¿Cuál es la forma más pitónica de calcular los cambios porcentuales en una lista de números?
- 4. ¿Cuál es la forma pitónica de calcular el producto escalar?
- 5. ¿Cuál es la forma más rápida de calcular la potencia grande de 2 módulo un número
- 6. ¿Cuál es la forma más fácil de agregar comas a un número entero?
- 7. ¿Cuál es la forma óptima de extraer valores entre llaves en bash/awk?
- 8. ¿Cuál es la forma idiomática de realizar una conversión/tipo de letra "entero" en javascript?
- 9. ¿Cuál es una mejor manera de verificar si una cadena es un número entero en iPhone?
- 10. grupo pitón una lista de número entero, con valores cercanos
- 11. En JavaScript/jQuery, ¿cuál es la mejor manera de convertir un número con una coma en un número entero?
- 12. ¿Cuál es la forma más rápida de calcular el número de bits necesarios para almacenar un número
- 13. ¿Cuál es una forma simple de calcular la superposición entre una imagen y un polígono?
- 14. ¿Cuál es la diferencia entre sscanf o atoi para convertir una cadena en un número entero?
- 15. ¿Cuál es la forma óptima de supervisar los cambios en un directorio con un kqueue()?
- 16. ¿Cuál es una buena manera de verificar si un doble es un número entero en C#?
- 17. ¿Cuál es la forma óptima de bucle entre dos fechas en Perl?
- 18. ¿Cuál es la mejor forma de calcular la matriz fundamental de una cadena de Markov absorbente?
- 19. Python: Redondo al siguiente número entero predefinido en la lista
- 20. ¿Cuál es la mejor forma de evitar la falta de memoria (OOM) en Linux?
- 21. ¿Cuál es una forma rápida de calcular la correlación columna por columna en matlab
- 22. ¿Cuál es la forma más fácil de llenar los vacíos en una lista de números?
- 23. ¿La inserción es óptima?
- 24. ¿Cuál es la forma correcta de verificar si un valor es una fecha/número en Delphi
- 25. ¿Cuál es la forma óptima de organizar un proyecto de C#?
- 26. ¿Cuál es la duración óptima para la contraseña del usuario?
- 27. ¿Cuál es la forma óptima multiplataforma de manejar cadenas Unicode bajo C++?
- 28. ¿Cuál es la forma más sencilla de vincular una lista de casillas de verificación a una lista de valores comprobados
- 29. Desarrollo iOS: ¿Cuál es una forma simple de calcular el número de segundos que han pasado entre dos eventos?
- 30. ¿Cuál es la longitud óptima para una dirección de correo electrónico en una base de datos?
Considere cómo sería el rango si lo ordenase. Si puede pensar en una palabra que comienza con "P", está en el camino correcto. –
¿Pero no ordenarlo requeriría más trabajo que mi método? (Y lo siento, no puedo pensar en la palabra) – CSturgess
No estoy diciendo que la clasificación sea la respuesta, solo que deberías pensar en cómo se vería. La segunda letra es "e". –