力扣 (LeetCode) 74. 搜索二维矩阵(C语言)

一、环境说明

  1. 本文是 leetcode 74题 :搜索二维矩阵,使用c语言实现
  2. 使用二分搜索实现。
  3. 测试环境:Visual Studio 2019

二、代码展示

// m = matrixSize   行数
// n = matrixColSize[0] 列数
// m*n对应总元素
// 求 mid 对应下标 
// 行(row)=(mid+1)%n == 0?(mid+1)/n-1:(mid+1)/n
// 列(column)=mid%n
// if(matrix[row][column]>=target) {right = mid - 1;}
bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {
    int left = 0, right = matrixSize * matrixColSize[0] - 1, mid = 0, row = 0, column = 0;
    while (left <= right) {//二分搜索
        mid = left + ((right - left) >> 1);
        row=(mid+1)%matrixColSize[0]==0?(mid+1)/matrixColSize[0]-1:(mid+1)/matrixColSize[0];
        column = mid % matrixColSize[0];
        if (matrix[row][column] >= target) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    row=(left+1)%matrixColSize[0]==0?(left+1)/matrixColSize[0]-1:(left+1)/matrixColSize[0];
    column = left % matrixColSize[0];
    if (row >= matrixSize || column >= matrixColSize[0]) {//其实就是没搜索到,left到矩阵外去了
        return false;
    }
    if (target == matrix[row][column]) {//找到了
        return true;
    }
    return false;
}

三、思路分析

  1. 代码思路见注释
  2. 这是一个从左到右,从上一行到下一行严格升序的二维矩阵,可以把前一行和后一行拼接起来,拼接所有行,就是一个一维有序数组,通过二分搜索,我们可以得到target在数组里的下标。我们脑子里有这个一维数组就可以了,实际上,直接操作二维矩阵可以减少时空复杂度。可以用一些小学奥数知识,将数组下标转换成矩阵的行号和列号。具体操作看代码注释。
  3. 需要注意的是,我们搜索到的left是最终的数组下标,在判断它对应的元素和target是否相同前,需要判断left是否超出矩阵范围。这是因为二分搜索的边界问题,比如对于1*1矩阵,当target大于矩阵中那一个元素,二分搜索的left最终是1,但矩阵的边界是0行0列,此时就造成了越界。需要提前判断,left越界,答案肯定是错误的,而且也不能去越界访问内存,编译器会抛出异常,OJ平台报heap-buffer-overflow。
  4. 这道题还有一个奇妙的思路,因为矩阵按列也是递增的,那么可以对第一列进行二分查找,找到最后一个小于等于target的行号,在这一行里,一定包括target这个元素,因为下一行的首元素就大于target,或者下一行不存在了,找到这一行,再进行一次二分查找,如果找到target,返回true,找不到,返回false即可。时空复杂度和本题解法一样,但是思路很有意思,读者可以自行实现。

四、AC

AC

五、复杂度分析

  1. 时间复杂度:O(lognm),n是矩阵的行数,m是矩阵的列数。
  2. 空间复杂度:O(1),除了若干变量使用的常量空间,没有使用线性空间。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清墨韵染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值