2010-03-08 14 views
28

[Descripción] Dadas dos matrices de enteros con la misma longitud. Diseña un algoritmo que pueda juzgar si son iguales. La definición de "igual" es que, si estas dos matrices estuvieran ordenadas, los elementos en la posición correspondiente deberían ser iguales.Compara dos matrices de enteros con la misma longitud

[Example] 
<1 2 3 4> = <3 1 2 4> 
<1 2 3 4> != <3 4 1 1> 

[Limitación] El algoritmo debe requerir espacio adicional constante, y O (n) tiempo de ejecución.

+1

Ya etiquetado como interview question. – Kibbee

+1

Hum ...Tal vez tratando de engañarte, porque el enfoque obvio es O (1) para el espacio y O (n) para el tiempo ... ¿Dónde está el truco? – mjv

+3

@mjv: si tiene una solución O (n), dígale. –

Respuesta

4

Usted puede tratar de un enfoque probabilístico - convertir las matrices en una serie de alguna enorme base B y mod por algún primo P, por ejemplo suma B^a_i para todos i mod algunos grandes-ish P. Si ambos salen al mismo número, intente de nuevo tantos primos como desee. Si es falso en cualquier intento, entonces no es correcto. Si pasan suficientes desafíos, entonces son iguales, con alta probabilidad.

Hay una prueba trivial de B>N, P> número más alto. Entonces debe haber un desafío que no se puede cumplir. En realidad, este es el enfoque determinista, aunque el análisis de complejidad podría ser más difícil, dependiendo de cómo la gente vea la complejidad en términos del tamaño de la entrada (en oposición a solo el número de elementos).

+0

Siempre hay una posibilidad de colisión. –

+0

No estoy convencido de que esto sea 100%, pero bueno, si estás en una entrevista, puedes hacerlo peor, probablemente. – Larry

+0

ejemplo de colisión? – Timmy

2
  1. Insertar todos los elementos de la primera matriz en una tabla hash
  2. intenta insertar todos los elementos de la segunda matriz en la misma tabla hash - para cada inserto de elemento ya debería estar allí

Ok, esto no es con un espacio extra constante, pero es lo mejor que puedo encontrar en este momento :-). ¿Hay otras restricciones impuestas a la pregunta, como por ejemplo al entero más grande que se puede incluir en la matriz?

+1

"Inserta todos los elementos de la primera matriz en una tabla hash". Necesitas una memoria O (n) para asignar una tabla hash, mientras que solo tienes O (1). –

+0

@Pavel: no, no necesitas O (n). O (n) sería que si las matrices duplicaran su tamaño (por ejemplo), esperaría que la tabla hash (también) duplicara (aproximadamente) el tamaño. Ese no es el caso en absoluto. –

+0

@Pavel en el peor de los casos Necesito O (n), lo dije en mi publicación. Soy consciente de que esta es solo una solución parcial, pero tal vez se pueda mejorar. – pajton

14

(probablemente demasiado complejo para una pregunta de la entrevista.)

(Puede utilizar O (N) tiempo para comprobar el min, max, sum, SUMSQ, etc. son iguales primero.)

Uso no-extra-space radix sort para ordenar las dos matrices en el lugar. O (N) complejidad del tiempo, O (1) espacio.

Luego compárelos usando el algoritmo habitual. O (N) complejidad del tiempo, O (1) espacio.

(Proporcionada (max − min) de las matrices es de O (N k) con una k finito.)

+3

Solo si son enteros acotados. – Larry

+0

Dado que estamos hablando de una computadora aquí, siempre están limitados. De acuerdo, un número entero que ocupa (digamos) 16 gigabytes tendría un límite superior extremadamente grande, pero sigue siendo un límite. –

+1

Con esta lógica, puede decir que la solución "hashtable" ingenua es correcta, por el hecho de que acaba de establecer la tabla hash a un tamaño constante, pero enorme. – Larry

-1

Para cada matriz, utilizar el conteo técnica tipo para construir el recuento del número de elementos menos igual o igual a un elemento en particular. Luego compare las dos matrices auxiliares construidas en cada índice, si son iguales a las matrices r igual, de lo contrario, no lo son. La clasificación de recuento requiere O (n) y la comparación de matriz en cada índice es nuevamente O (n), por lo tanto, es totalmente O (n) y el espacio requerido es igual al tamaño de dos matrices. Aquí hay un enlace para contar el tipo http://en.wikipedia.org/wiki/Counting_sort.

+1

El espacio requerido es O (n). No vuela –

+0

Lo siento, creo que salté temprano – Nagaraj

2

Algunas respuestas son básicamente correctas, aunque no lo parezcan. El enfoque de tabla hash (para un ejemplo) tiene un límite superior basado en el rango tipo involucrado en lugar del número de elementos en las matrices. Al menos por la mayoría de las definiciones, eso hace que el (límite superior en) el espacio sea constante, aunque la constante puede ser bastante grande.

En teoría, podría cambiar eso de un límite superior a una cantidad constante de espacio. Sólo por ejemplo, si estuviera trabajando en C o C++, y era una matriz de char, podría utilizar algo como:

size_t counts[UCHAR_MAX]; 

Desde UCHAR_MAX es una constante, la cantidad de espacio utilizado por la matriz es también una constante.

Editar: Me gustaría tener en cuenta que un límite en los rangos/tamaños de los elementos implicados está implícito en casi todas las descripciones de complejidad algorítmica. Solo por ejemplo, todos "sabemos" que Quicksort es un algoritmo O (N log N). Sin embargo, eso solo es cierto si suponemos que comparar e intercambiar los elementos que se ordenan requiere tiempo constante, lo que solo puede ser cierto si vinculamos el rango. Si el rango de elementos implicados es lo suficientemente grande como para que no podamos tratar una comparación o un intercambio como tomar un tiempo constante, entonces su complejidad sería algo así como O (N log N log R), donde R es el rango, por lo que log R se aproxima la cantidad de bits necesarios para representar un artículo.

+2

No estoy de acuerdo contigo. De esta forma, todos los algoritmos que operan en O (n) serían constantes, porque si tiene una matriz de tamaño n, pero sabe que n se expresa como un número entero, tiene menos de MAX_INT elementos, por lo tanto constantes. – pajton

+0

Es lo que hace que estas preguntas de la entrevista sean académicas, a veces. 'O (N)' a toda costa no es práctico! – Larry

+0

@pajton: no es realmente comparable. Estás hablando de un límite en el tamaño de la matriz que se procesa. Estoy hablando de un límite en el rango de los elementos en la matriz, independientemente de su tamaño. –

1

¿Es esta una pregunta capciosa? Si los autores asumieron que los enteros se encuentran dentro de un rango determinado (2^32, etc.), entonces el "espacio extra constante" podría ser simplemente una matriz de tamaño 2^32 en la que se cuentan las ocurrencias en ambas listas.

Si los enteros son unranged, no se puede hacer.

0

Puede agregar cada elemento en un hashmap < entero, entero>, con las siguientes reglas: la matriz A es la sumadora, la matriz B es la removedora. Al insertar desde la matriz A, si la clave no existe, insértela con un valor de 1. Si la clave existe, incremente el valor (mantenga una cuenta). Al eliminar, si la clave existe y es mayor que 1, reduzca en 1. Si la clave existe y es 1, elimine el elemento.

Ejecutar a través del conjunto A seguido del conjunto B utilizando las reglas anteriores. Si en algún momento durante la fase de eliminación, el conjunto B no encuentra un elemento, puede devolverlo de inmediato. Si después de que tanto el sumador como el eliminador hayan finalizado, el hashmap está vacío, las matrices son equivalentes.

Editar: El tamaño de la tabla hash será igual al número de valores distintos en la matriz ¿se ajusta esto a la definición de espacio constante?

+0

No, no es igual a la longitud de la matriz, es igual al número de valores distintos en la matriz. – Svante

+0

@Svante: ¡Ups, cierto! – kgrad

-1

int dado están en el rango -n .. + na manera simple para comprobar la equidad puede ser el siguiente (pseudo código):

// a & b are the array 
accumulator = 0 
arraysize = size(a) 
for(i=0 ; i < arraysize; ++i) { 
    accumulator = accumulator + a[i] - b[i] 
    if abs(accumulator) > ((arraysize - i) * n) { return FALSE } 
} 
return (accumulator == 0) 

acumulador debe ser capaz de almacenar número entero con rango = + - arraysize * n

+1

Tu código no funciona correctamente para [1,2,4] [2,3,2] –

0

Imagino que la solución requerirá algún tipo de transformación que sea tanto asociativa como conmutativa y garantiza un resultado único para un conjunto único de entradas. Sin embargo, no estoy seguro de si eso existe.

+0

Estaba pensando algo así, por ejemplo. demostrando que para el subconjunto A, B de Z \ {0,1} donde | A | = | B |, luego si sum (a_i) = suma (b_i) y prod (a_i) = prod (b_i) debemos tener A = B después de alguna permutación ... la parte difícil es la prueba: P –

+1

¡Exactamente! Intenté usar sum() y prod() pero falló - en varias entradas, por ejemplo: [-10, -10, -10, -1, 9]! = [6, -3, 5, -10, - 10] pero sus sumas y productos son iguales. –

3

Yo afirmo que: A menos que se especifique el rango de entrada, entonces es IMPOSIBLE resolver en un espacio adicional, y O (n) tiempo de ejecución.

Me alegrará que se demuestre que estoy equivocado, por lo que puedo aprender algo nuevo.

+1

¿Puedes demostrar el límite inferior para este problema? – meta

+0

Estoy de acuerdo sin un rango de entero este problema no se puede resolver en O (n) tiempo y espacio constante. – faisal

-1

¿Qué tal esto? XOR todos los números en ambas matrices. Si el resultado es 0, tienes una coincidencia.

+2

XOR (1, 2, 3) = XOR (2, 4, 6) = 0 –

0
public static boolean match(int[] array1, int[] array2) { 

     int x, y = 0; 

     for(x = 0; x < array1.length; x++) { 
       y = x; 
       while(array1[x] != array2[y]) { 
         if (y + 1 == array1.length) 
           return false; 
         y++; 
       } 
       int swap = array2[x]; 
       array2[x] = array2[y]; 
       array2[y] = swap; 
     } 

     return true; 
} 
+0

Este es O (n^2) tiempo de ejecución. – jrouquie

Cuestiones relacionadas