java - 在亚线性时间搜索二维数组

标签 java arrays algorithm

<分区>

这是最近编码面试的问题

编写一个高效的算法来搜索 m x n 矩阵中的值。

此矩阵具有以下属性:

  1. 每行中的整数从左到右升序排列。

  2. 每列中的整数从上到下升序排列。
    .

      [1,   4,  7, 11, 15]
    
      [2,   5,  8, 12, 19]
    
      [3,   6,  9, 16, 22]
    
      [10, 13, 14, 17, 24]
    
      [18, 21, 23, 26, 30]
    

有没有办法在 O(mn) 以下执行此操作。我看不出如何对该数组进行二进制搜索,因为无法消除任何内容。

最佳答案

您可以使用这个简单的算法,它利用了这样一个事实,即在具有这些属性的矩阵中,mtx[i][j] 的值总是小于任何值mtx[x][y],其中 x > iy > j,换句话说,向右和向下的任何值:

public static boolean find(int[][] mtx, int val) {
    int maxCol = mtx[0].length, minCol = 0;

    for(int i = 0 ; i < mtx.length ; i++) {
        for(int j = minCol ; j < maxCol ; j++) {
            if(val == mtx[i][j]) return true;

            if(val < mtx[i][j]) {
                maxCol = j;
                break;
            }
        }

        if(maxCol == 0) break;

        minCol = 0;
        if(i != mtx.length-1 && val > mtx[i+1][maxCol-1]) minCol = maxCol-1;
    }

    return false;
}

想法是逐行搜索,如果找到更大的值,则可以停止在该行中查找,并且您知道不必在以后的行中搜索超出该列的内容。如果一行的第一个值大于该值,则可以停止搜索并返回 false。此外,在每行搜索结束时,您检查下一行的单元格 maxCol-1,如果值较大,则在下一个循环中,您可以跳过前面的每个单元格。

最坏的情况是最大值(或更大),复杂度为 O(m+n),因为它会检查所有第一行,然后跳过接下来的 m 行。

关于java - 在亚线性时间搜索二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36815652/

相关文章:

java - Java-Spring-Hibernate 中的日期格式发生变化

java - 如何解决这个数组越界异常?

algorithm - 当网格图中有多个目标时,如何设计 A* 的启发式?

arrays - 错误 : accessing members of protocol type value 'String' is unimplemented

javascript - 替换重复的字符不起作用

java - 快速选择分区

algorithm - 根据样本运行估算模拟运行时间

java - ComponentListener 不工作

java - 将字符串数组从 red5 (Java) 发送到 Flash (ActionScript 3)?

javascript - 无法设置/读取未定义的属性