我坚持以下问题:
给定大小为n 2 的int二维矩阵
mat
,其中n = 2 k ,搜索整数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);
}
请告知。
答案 0 :(得分:1)
如果您的矩阵行和列已排序,您可以使用以下代码。
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;
}
答案 1 :(得分: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);
这解决了问题,并为true
返回-2
。
更新代码:
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);
}