可能重复:
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
一种节省时间的程序,用于在二维矩阵中查找元素,其行和列单调增加。 (行和列从上到下,从左到右)。
如果2D数组已经排序,我只能想到二分搜索。
答案 0 :(得分:14)
我把这个问题作为上学期的家庭作业提出来,而我认为是平均水平的两个学生通过提出一个非常优雅,直截了当,(可能)最优的算法让我感到惊讶:
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)并且正如克里斯指出的那样,最初应该使用“右上角”调用,即Find( k,tab,n,1),其中 n 是行数。
答案 1 :(得分:5)
由于行和列的单调增加,你可以像这样做一个简洁的小搜索:
从左下角开始。如果您要查找的元素大于该位置的元素,请向右移动。如果它少了上去。重复,直到找到元素或者你到达边缘。示例(以十六进制格式化,使格式更容易):
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<我们就这样上去吧。在(1,2):7,8> 7所以我们走对了(2,2):8 - > 8 == 8所以我们完成了。
但是,您会注意到,它只发现了一个值为8的元素。
编辑,如果不明显,则会在O(n + m)平均和最差情况下运行。
答案 2 :(得分:0)
假设我读得正确,你说第n行的底部总是小于第n + 1行的顶部。如果是这种情况,那么我会说最简单的方法是使用二进制搜索搜索第一行中的数字或下一个最小数字。然后你将确定它所在的列。然后对该列进行二进制搜索,直到找到它为止。
答案 3 :(得分:0)
从(0,0)开始
重复这些步骤应该会带你到达目标。