【问题标题】:Algorithm: efficient way to search an integer in a two dimensional integer array? [duplicate]算法:在二维整数数组中搜索整数的有效方法? [复制]
【发布时间】:2011-03-29 11:49:22
【问题描述】:

可能的重复:
Given a 2d array sorted in increasing order from left to right and top to bottom, what is the best way to search for a target number?
Search a sorted 2D matrix

在二维矩阵中查找元素的高效程序,其行和列单调递增。 (行和列从上到下,从左到右递增)。

如果对二维数组进行排序,我只能想到二分查找。

【问题讨论】:

  • 即使单调递增而不是排序,也可以进行一种二分搜索,但正如所指出的,还有更好的方法。

标签: algorithm


【解决方案1】:

上学期我把这个问题作为家庭作业,两个我认为一般的学生提出了一个非常优雅、直接且(可能)最优的算法,这让我感到惊讶:

Find(k, tab, x, y)
  let m = tab[x][y]

  if k = m then return "Found"
  else if k > m then
    return Find(k, tab, x, y + 1)
  else
    return Find(k, tab, x - 1, y)

此算法在每次调用时消除一行或一列(注意它是尾递归的,可以转换为循环,从而避免递归调用)。因此,如果您的矩阵是 n*m,则算法在 O(n+m) 中执行。这个解决方案比二分搜索衍生产品(我在解决这个问题时所期望的解决方案)要好。

编辑:我修正了一个错字(k 在递归调用中变成了 x),而且,正如 Chris 指出的,这最初应该用“右上角”调用,即 Find( k, tab, n, 1),其中 n 是行数。

【讨论】:

  • 秒杀我!顺便说一句,对 Find 的第二次递归调用需要大写。
  • 什么是 z?那应该是m吗?
  • @Chris:是的,“z”应该再次“m”,我在您阅读时更正了这一点。 @Niki:哈哈哈,你只是想让我编辑我的帖子,这样时间戳就会改变,看起来我在阅读你的帖子后修改了我的答案:-D
  • 我给你做个交易,你编辑你的,我来编辑我的:)。
  • 另外,为了澄清,我认为您从调用 Find 开始,x,y 是矩阵的右上角(即 x 从最大值开始,y 从最小值开始),我是否正确?
【解决方案2】:

由于行和列单调增加,您可以像这样进行简洁的小搜索:

从左下角开始。如果您要查找的元素大于该位置的元素,请向右走。如果少了就上去。重复直到找到元素或碰到边缘。示例(十六进制以使格式化更容易):

1 2 5 6 7
3 4 6 7 8
5 7 8 9 A
7 A C D E

让我们搜索 8。从位置 (0, 3) 开始:7. 8 > 7 所以我们向右走。我们现在在 (1, 3): A. 8 7 所以我们向右走。 (2, 2): 8 -> 8 == 8 所以我们完成了。

但是,您会注意到,它只找到了值为 8 的元素之一。

编辑,以防它在 O(n + m) 平均和最坏情况下运行时间不明显。

【讨论】:

    【解决方案3】:

    假设我没看错,你是说第 n 行的底部总是小于第 n+1 行的顶部。如果是这种情况,那么我想说最简单的方法是使用二进制搜索来搜索第一行,以查找数字或下一个最小的数字。然后您将确定它所在的列。然后对该列进行二进制搜索,直到找到它为止。

    【讨论】:

      【解决方案4】:

      从 (0,0) 开始

      • 当值太低时,继续向右 (0,1),然后 (0,2) 等等。
      • 当达到一个过高的值时,下一个左一个 (1,1)

      重复这些步骤应该会让你达到目标。

      【讨论】:

      • 这行不通。如果您查看我的示例矩阵,请尝试搜索 3。您将找到 (0,0):1 > (1,0):2 > (2,0):5 v (1, 1):4 v ( 0, 2): 5 下一步将带你离开边缘(我认为这将是“未找到”的情况)。
      猜你喜欢
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 2018-02-21
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 2015-03-21
      • 1970-01-01
      相关资源
      最近更新 更多