二分法-LeetCode74

题目内容

基本描述

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:(1)每行中的整数从左到右按升序排列;(2) 每行的第一个整数大于前一行的最后一个整数。

实例

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false

算法求解-一次二分查找

思路

将每一行进行顺序拼接,可以得到一个升序数组,然后使用二分查找。代码实现时,可以二分升序数组的下标,将其映射到原矩阵的行和列上。

代码

public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int low = 0, high = m * n - 1;
        while (low <= high){
            int mid = (high-low)/2 + low;
            int x = matrix[mid/n][mid%n];
            if (x > target){
                high = mid - 1;
            }else if (x < target){
                low = mid + 1;
            }else {
                return true;
            }
        }
        return false;
    }

复杂度分析

时间复杂度:二分法,为 O ( l o g   m n ) O(log\ mn) O(log mn),其中m和n分别是矩阵的行数和列数。
空间复杂度:只使用了mid、low和high三个参数,为 O ( 1 ) O(1) O(1)

算法求解-两次二分查找

思路

第一列是升序的;同时每行也是升序的。所以可以先查找在哪一行,然后再查找在该行的哪一列,两次查找都使用二分法。查找在哪一行时,针对第一行进行查找,寻找最后一个不大于target的位置。

代码

public boolean searchMatrix(int[][] matrix, int target) {
        int rowIndex = binarySearchFirstColumn(matrix, target);
        if (rowIndex == -1){
            return false;
        }

        return binarySearchRow(matrix[rowIndex], target);
    }

    public int binarySearchFirstColumn(int[][] matrix, int target){
        int low = -1, high = matrix.length - 1;
        while (low < high){
            int mid = (high-low+1)/2 + low;
            if (matrix[mid][0] <= target){
                low = mid;
            }else {
                high = mid - 1;
            }
        }
        return low;
    }

    public boolean binarySearchRow(int[] row, int target){
        int low = 0, high = row.length - 1;
        while (low <= high){
            int mid = (high-low)/2 + low;
            if (row[mid] < target){
                low = mid + 1;
            }else if (row[mid] > target){
                high = mid - 1;
            }else {
                return true;
            }
        }
        return false;
    }

复杂度分析

时间复杂度:两次二分,为 O ( l o g   m + l o g   n ) = O ( l o g   m n ) O(log\ m+log\ n) = O(log\ mn) O(log m+log n)=O(log mn),其中m和n分别是矩阵的行数和列数。
空间复杂度: O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值