简体   繁体   中英

Binary Search 2D array - Java

I am stuck on the following question:

Given a int two-dimensional matrix mat of size n 2 where n = 2 k , search for an integer k.

The matrix's rows and columns are sorted.

If we split the matrix in quarters, each quarter is also sorted. For example, given this matrix:

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

If we split it into quarters, we can see that all of the numbers in the first quarter are equal or less than numbers in the second quarter.

In order to obtain an efficient algorithm, I thought of making a recursive binary search in on the two dimensions but it fails to search for 2 on the previous matrix.

Here's the code:

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);
}

Please advise.

Your mistake is at here in your code.

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);

Here in first two functions, You are removing middle column from your search space. You need to include it as element can be present at the middle column . Another mistake is in the last call find2(mat,x,midrow+1,hirow,midcol+1,hicol) .

If your search element is smaller than the middle element, You should choose top-left quadrant of the middle element and ignore the bottom-right quadrant. You have mistakenly considered here bottom-right quadrant over top-left quadrant.

After making changes accordingly the return function in else looks like:

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

This solved the problem and it returns true for -2 .

Updated Code:

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);
}

If your matrix row and column are sorted you can use below code.

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;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM