我有一个使用二进制搜索搜索二维数组的程序。在这种情况下,我使用下面的矩阵并搜索整数4,12,110,5,111。该程序找到所有这些除了110和111为什么这是?
{1,3,7,8,8,9,12},
{2,4,8,9,10,30,38},
{4,5,10,20,29,50,60},
{8,10,11,30,50,60,61},
{11,12,40,80,90,100,111},
{13,15,50,100,110,112,120},
{22,27,61,112,119,138,153},
public static boolean searchMatrix(int[][] matrix, int p,int n) {
int low = 0, high = n-1 ;
while (low < high) {
int mid = (low + high) / 2;
if (p == matrix[mid][0])return true;
else if (p < matrix[mid][0]) high = mid - 1;
else if (p < matrix[mid+1][0]) { low = mid; break; }
else low = mid + 1;
}
int row = low;
low = 0; high = matrix[row].length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (p == matrix[row][mid]) return true;
else if (p < matrix[row][mid]) high = mid - 1;
else low = mid + 1;
}
return false;
}
答案 0 :(得分:0)
我宁愿说你的算法在第一时间找到4,5和12或多或少是一个惊喜。原因是4出现在行的第一个位置,5和12满足它们小于下一行中第一个元素的条件。只是因为这个事实才发现它们在算法的后半部分。该算法有点难以阅读,我没有评估+/- 1魔法,但似乎算法期望110和111实际上发生在最后一行(因为110和111都大于22)他们在那里他们不是。
如果我找对你,那么你的方法是有缺陷的,因为通过查看一个数字实际上是不可能的,告诉它会发生什么行,这是你第一次尝试实现的。因此,首先选择一行然后搜索列的任何两阶段算法都必须失败。
由于您对矩阵的限制很少(每行和每列都已排序),所以二进制搜索似乎根本不起作用:即使您的边界low
和high
也是如此是2D点它不会帮助很多。考虑矩阵中任何大于搜索点的元素。然后,您可以说的是,您的搜索点不位于该元素的和右侧(而您希望能够得出的结论是它是左侧和上方,但这不一定是真的 - 它可以在上方和右侧,左侧和下方),因此您只会切断搜索空间的一小部分。
答案 1 :(得分:0)
您的问题是您假设您可以先锁定搜索值的行,然后在该行轻松进行二进制搜索。事实并非如此。
对于110和111,每行的第一个元素总是小于您的搜索值,并且您的算法得出错误的结论,这意味着您的行必须是第一个循环后索引为6的数组。事实并非如此。
它适用于小数字的原因是因为你的算法足够幸运地锁定第一个循环中的右行......
快速搜索2d矩阵的一种正确算法,其中每行和每列按升序排序如下:
1)从右上角开始元素2)循环:将此元素e与x进行比较 ...... .i)如果它们相等则返回其位置...... ii)e&lt; x然后移动 它向下(如果超出矩阵然后断开返回false)..iii) e> x然后将其移动到左边(如果超出矩阵的界限则打破 返回false)3)重复i),ii)和iii),直到找到元素或 返回false
我在这里找到了这个算法:http://www.geeksforgeeks.org/search-in-row-wise-and-column-wise-sorted-matrix/
对于n×n矩阵,它是O(n)。