剑指 Offer 04. 二维数组中的查找
有序+查找,典型的二分查找问题。不同的是把一维问题改为二维问题,但只要把握住二分查找的本质,还是很容易解决的。
二分查找的本质:通过数组已排序的特性,用一次比较得出的信息来避免冗余的比较,从而减少比较次数。
在本题中,易知对于任意位置的数字,其左上角部分的总小于它,其右下角部分的总大于它,其他位置则不能确定。类比二分查找的思想即可写出代码
bool findNumber(int** matrix,int start_x,int start_y,int end_x,int end_y,int target){
//printf("%d %d\n",matrix[start_x][start_y],matrix[end_x][end_y]);
if(start_x == end_x && start_y == end_y){
return matrix[start_x][start_y] == target;
}
//与二分类似,不要忘记越界检查
else if(start_x > end_x || start_y > end_y || target < matrix[start_x][start_y] || target > matrix[end_x][end_y]){
return 0;
}
else{
int mid_x = (start_x + end_x)/2;
int mid_y = (start_y + end_y)/2;
int res = findNumber(matrix,start_x,mid_y+1,mid_x,end_y,target) || findNumber(matrix,mid_x+1,start_y,end_x,mid_y,target);
if(matrix[mid_x][mid_y] == target){
return 1;
}
else if(matrix[mid_x][mid_y]>target){
return findNumber(matrix,start_x,start_y,mid_x,mid_y,target) ||
res;
}
else{
return findNumber(matrix,mid_x+1,mid_y+1,end_x,end_y,target) ||
res;
}
}
}
bool findNumberIn2DArray(int** matrix, int matrixSize, int* matrixColSize, int target){
if(!matrixSize || !matrixColSize[0]) return 0;
int end_x = matrixSize-1;
int end_y = matrixColSize[0]-1;
return findNumber(matrix,0,0,end_x,end_y,target);
}
附一个最快写法,从第一排最后一个开始,小左大下
bool findNumberIn2DArray(int** matrix, int matrixSize, int* matrixColSize, int target){
int a=* matrixColSize-1,b=0;
//printf("%d,%d,%d",a,matrixSize);
if (matrixSize == 0 || *matrixColSize == 0)
{
return 0;
}
while(a>=0 && b<matrixSize)
{
if(matrix[b][a]==target)
{
return 1;
}
else if(matrix[b][a]>target)
{
a=a-1;
}
else
{
b=b+1;
}
}
return 0;
}