如何有效地搜索有序矩阵?

时间:2010-09-16 02:43:39

标签: arrays algorithm search matrix

我有xy矩阵,其中每行和每列按升序排列。

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

如何在此矩阵中搜索O(x+y)中的数字?

我被问到这个问题接受采访,但无法弄明白。很想知道是否可以做到。

3 个答案:

答案 0 :(得分:43)

从第一行的最后一个元素开始(右上角)。
将其与key进行比较。我们有3个案例:

  • 如果他们是平等的,我们就完成了。

  • 如果key大于该元素 那意味着key不能出现 在那一行,所以移动搜索 到它下面的元素。

  • 如果key小于那个元素那么 这意味着key可能存在于其中 向左行并且不能在列中进一步向下,因此移动搜索 到它左边的元素。

继续这样做,直到找到元素或者你无法进一步移动(键不存在)。

伪代码:

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

答案 1 :(得分:5)

将矩阵拆分为4个子矩阵。如果子矩阵的右下角小于键,则丢弃它。如果子矩阵的左上角大于键,则丢弃它。对剩余的子矩阵重复分割过程。

[更新] 对于一些伪代码(以及对复杂性的讨论),请参阅Jeffrey L Whitledge对this question的回答。

答案 2 :(得分: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;
}

实际上,我们可以使用二次搜索两次,先通过二进制搜索找到目标行,然后通过二进制搜索找到行中的目标,因此时间复杂度为O(lgx)+ O(lgy),为O( lgx + lgy),更好的是O(x + y)。