剑指 Offer 04. 二维数组中的查找

剑指 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值