74. 搜索二维矩阵

74. 搜索二维矩阵

题目介绍

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。

示例 1:
在这里插入图片描述

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

在这里插入图片描述

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

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-a-2d-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

贪心算法

先向下搜索,查看target应该属于哪一行;
之后对该行向右搜索,查看是否有target值。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        // 先找目标值属于哪一行
        int i, j=0;
        int m=matrix.size(), n=matrix[0].size();
        for(i=0; i<m-1; i++) //属于第i行
        {
            if(matrix[i+1][0]>target)
            {
                break;
            }
        }
        while(j<n)
        {
            if(matrix[i][j]==target) return true;
            else if(matrix[i][j]<target)
            {
                j++;
            }
            else{ //未找到
                return false;
            }
        }
        return false;
    }
};

时间复杂度为 O ( m + n ) O(m+n) O(m+n)

两次二分查找

对于向下搜索和向右搜索,都是一个有序数组查找的问题,因为可以用二分查找来优化。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int i;
        int m=matrix.size(), n=matrix[0].size();
        // 先找目标值属于哪一行
        int left=0, right=m-1, mid;
        while(left<=right)
        {
            mid = (left+right)/2;
            if(matrix[mid][0]==target) return true;
            else if(matrix[mid][0] > target) right = mid-1;
            else left = mid+1;
        }
        i = right; //属于第i行
        if(i<0) //防止出现所有数都大于target i=-1的情况
        {
            return false;
        }
        left = 0, right = n-1;
        // 查看第i行的元素
        while(left<=right)
        {
            mid = (left+right)/2;
            if(matrix[i][mid]==target) return true;
            else if(matrix[i][mid] > target) right = mid-1;
            else left = mid+1;
        }
        return false;
    }
};

时间复杂度为 O ( l o g m + l o g n ) = O ( l o g m n ) O(logm+logn)=O(logmn) O(logm+logn)=O(logmn)

一次二分查找

再次观察,我们可以发现这个二维数组按行排列之后可以变成一个一维有序数组。因此我们可以假设 A [ i ] [ j ] = B [ k ] A[i][j] = B[k] A[i][j]=B[k] 的一个有序数组,使用一次二分查找即可。

i = k / n , j = k i = k/n, j=k%n i=k/n,j=k,其中 n 为列的长度。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m=matrix.size(), n=matrix[0].size();
        int left=0, right=m*n-1, mid;
        while(left<=right)
        {
            mid = (left+right)/2;
            if(matrix[mid/n][mid%n]==target) return true;
            else if(matrix[mid/n][mid%n] > target) right = mid-1;
            else left = mid+1;
        }
        return false;
    }
};

时间复杂度为 O ( l o g m n ) O(logmn) O(logmn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值