2010-09-16 18 views
28

Tengo una matriz x por y, donde cada fila y cada columna están en orden ascendente como se indica a continuación.¿Cómo buscar eficientemente en una matriz ordenada?

1 5 7 9 
4 6 10 15 
8 11 12 19 
14 16 18 21 

Cómo buscar esta matriz por un número en O(x+y)?

Me hicieron esta pregunta para una entrevista, pero no pude encontrar el camino. Es curioso saber si podría hacerse.

+0

suena similar a esto http://geeksforgeeks.org/forum/topic/amazon-interview-question-for-software-engineerdeveloper-about-algorithms-10 –

Respuesta

43

Comience en el último elemento de la primera fila (esquina superior derecha).
Compararlo con key. Tenemos 3 casos:

  • Si son iguales, hemos terminado.

  • Si key es mayor que el elemento entonces significa key no puede estar presente en esa fila así mover la búsqueda de al elemento por debajo de ella.

  • Si key es menor que el elemento continuación que significa key podrían estar presentes en esa fila hacia la izquierda y no puede estar presente en la columna más abajo, por lo que mover la búsqueda de al elemento que queda de ella.

Siga haciéndolo hasta que encuentre el elemento o no podrá seguir moviéndose (la clave no existe).

pseudo código:

Let R be number of rows 
Let C be number of columns 

Let i = 0 
Let j = C-1 

found = false 
while(i>=0 && i<R) && (j>=0 && j<C)) 
    if (matrix[i][j] == key) 
     found = true 
     break 
    else if(matrix[i][j] > key) 
     j-- 
    else if(matrix[i][j] < key) 
     i++ 
end-while 
+0

No puedo ver que esto funcione. Supongamos que estoy buscando key = 11 en la matriz anterior, ¿cómo lo encuentra este algo? – Ashley

+2

@ Ashley: Comenzamos en '9'. '11'>' 9' así que muévete hacia abajo. '11' <' 15' movimiento hacia la izquierda. '11'>' 10' mueve hacia abajo. '11' <' 12' mueve hacia la izquierda. '11' ==' 11' – codaddict

+0

@codeaddict lo tengo, ¡gracias! – Ashley

5

Dividir la Matriz en 4 submatrices. Si la parte inferior derecha de una submatriz es menor que la clave, deséchela. Si la parte superior izquierda de una submatriz es más grande que la clave, deséchela. Repita el procedimiento de división para las submatrices restantes.

[Actualización] Para algunos pseudocódigos (y una discusión sobre la complejidad), vea la respuesta de Jeffrey L Whitledge this question.

+0

Eso debería tener un rendimiento aún mejor: O (log x + log y)?! –

+0

Puede ser más rápido, pero necesita más memoria. – Landei

+0

¿Cómo dividirás la matriz en 4 submatrices? ¿Hasta cuándo vas a repetir?¿Cuándo sabrá que el elemento no está presente? Comience a escribir el código psuedo y encontrará que esto no es tan fácil. @Landei - ¿No será la memoria lo mismo que x * y? –

0
// the matrix is like this, from left to right is ascending, and 
// from down to up is ascending, but the second row'start is not always bigger than the first row's end, which is diff from [leetcode]https://oj.leetcode.com/problems/search-a-2d-matrix/ 
// 1 5 7 9 
// 4 6 10 15 
// 8 11 12 19 
// 14 16 18 21 
// time complexity is O(x+y), x is the count of row, and y is the count of column 

public boolean searchMatrix2(int[][] matrix, int target) { 
    int rowCount = matrix.length; 
    if(rowCount == 0) return false; 

    int colCount = matrix[0].length; 
    if(colCount == 0) return false; 

    //first find the target row, needs O(x) 
    int targetRow = 0; 
    while(targetRow < rowCount-1 && matrix[targetRow+1][0] <= target) { 
     targetRow++; 
    } 
    //than find the target in the target row, needs O(y), so the total is O(x)+O(y) 
    boolean result = false; 
    for(int i = 0; i < colCount; i ++) { 
     if(matrix[targetRow][i] == target) { 
      result = true; 
      break; 
     } 
    } 
    return result; 
} 

En realidad, podemos usar la búsqueda binaria dos veces, encontrar la fila de destino mediante una búsqueda binaria en primer lugar, a continuación, encontrar el objetivo en la fila de búsqueda binaria, por lo que el tiempo de complejidad es O (lgx) + O (lgy) , es O (lgx + lgy), mejor el O (x + y).

Cuestiones relacionadas