【问题标题】:Binary Search 2D array - Java二分搜索二维数组 - Java
【发布时间】:2017-06-11 02:45:08
【问题描述】:

我被以下问题困扰:

给定一个大小为 n2 其中 n = 2k 的 int 二维矩阵 mat,搜索整数 k。

矩阵的行和列已排序。

如果我们将矩阵分成四等份,每个季度也会被排序。例如,给定这个矩阵:

-4 -2 5  9
 2  5 12 13
13 20 25 25
22 24 49 57  

如果我们把它分成四等份,我们可以看到第一季度的所有数字都等于或小于第二季度的数字。

为了得到一个高效的算法,我想在二维上进行递归二分搜索,但是在前面的矩阵上搜索不到2

代码如下:

public static boolean find(int[][] mat, int x){
    return find2(mat, x, 0, mat.length-1,0, mat.length-1);
}

private static boolean find2(int[][] mat, int x, int lorow, int hirow,int locol,int hicol){
    if(mat.length==0) return false;
    if(lorow>hirow || locol>hicol) return false;
    int midrow=(lorow+hirow)/2;
    int midcol=(locol+hicol)/2;
    if(mat[midrow][midcol] == x ) return true;
    else if(mat[midrow][midcol] < x) 
        return find2(mat,x,lorow,midrow,midcol+1,hicol) || find2(mat,x,midrow+1,hirow,locol,midcol) || find2(mat,x,midrow+1,hirow,midcol+1,hicol);
    else 
        return find2(mat,x,lorow,midrow,locol,midcol-1) || find2(mat,x,midrow,hirow,locol,midcol-1) || find2(mat,x,midrow+1,hirow,midcol+1,hicol);
}

请指教。

【问题讨论】:

标签: java binary-search


【解决方案1】:

你的错误在你的代码中。

else 
    return find2(mat,x,lorow,midrow,locol,midcol-1) || find2(mat,x,midrow,hirow,locol,midcol-1) || find2(mat,x,midrow+1,hirow,midcol+1,hicol);

在前两个函数中,您将从搜索空间中删除 middle column。您需要包含它,因为元素可以存在于middle column。另一个错误是在最后一次通话中find2(mat,x,midrow+1,hirow,midcol+1,hicol)

如果你的搜索元素小于中间元素,你应该选择中间元素的top-left象限,忽略bottom-right象限。您在这里错误地考虑了bottom-right 象限而不是top-left 象限。

进行相应更改后,else 中的返回函数如下所示:

return find2(mat,x,lorow,midrow,locol,midcol) || find2(mat,x,lorow,midrow,midcol+1,hicol) ||find2(mat,x,midrow+1,hirow,locol,midcol);

这解决了问题,它为-2 返回true

更新代码:

private static boolean find2(int[][] mat, int x, int lorow, int hirow,int locol,int hicol){
    if(mat.length==0) return false;
    if(lorow>hirow || locol>hicol) return false;

    if(lorow==hirow && locol==hicol && mat[lorow][locol]!=x)
        return false;

    int midrow=(lorow+hirow)/2;
    int midcol=(locol+hicol)/2;

    if(mat[midrow][midcol] == x ) return true;
    else if(mat[midrow][midcol] < x) 
        return find2(mat,x,lorow,midrow,midcol+1,hicol) || find2(mat,x,midrow+1,hirow,locol,midcol) || find2(mat,x,midrow+1,hirow,midcol+1,hicol);
    else 
        return find2(mat,x,lorow,midrow,locol,midcol) || find2(mat,x,lorow,midrow,midcol+1,hicol) ||find2(mat,x,midrow+1,hirow,locol,midcol);
}

【讨论】:

  • 非常感谢朋友,但您的代码中有一个错误。例如,如果您插入输入(例如 0)或小于矩阵中第一个数字(例如 -6)的数字,则会出现堆栈溢出错误。
  • @Meni,是的,这个条件还有待检查。您可以添加它来终止递归调用。
【解决方案2】:

如果您的矩阵行和列已排序,您可以使用以下代码。

public int search(int mat[][], int n, int x) {
        int i = 0, j = n - 1;
        while (i < n && j >= 0) {
            if (mat[i][j] == x) {
                System.out.println("Found at" + i + j);
                return 1;
            }
            if (mat[i][j] > x)
                j--;
            else // if mat[i][j] < x
                i++;
        }

        System.out.println("not Found at");
        return 0;
    }

【讨论】:

  • 感谢您的评论,但您的回答与我的问题无关。您的代码的复杂性是 O(n^2) 的顺序,这不好
  • 我认为是 O(n),对于 mn 矩阵,它将是 O(m+n)。你能解释一下 O(nn )
  • 是的,我很抱歉它的 O(n),但我试图在这里实现的答案是 O(log(n))
  • @gati sahu 你的代码有错误 int[][] data = { {10,20,30,40}, {15,25,35,45}, {27,29,37, 48}, {32,33,39,50} };它将无法找出存在于 2,3 的 33
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 2017-03-26
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多