每日一题-搜索二维矩阵

131 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

每日一题——搜索二维矩阵

题目信息描述

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

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

示例 1:

image-20220426112009701

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

示例 2:

image-20220426112017735

输入: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

思路

解法一:

可以根据矩阵的排列顺序得出规律,即:每一行的最后一个数一定大于每一行的第一个数,且小于第二行的最后一个数字,于是我们可以从第一行的右上角进行搜寻,如果这个数大于target,那么列-1,否则行+1,这样就可以搜寻出答案。

注意:这样的时间复杂度为O(n + m)

解法二:

这个做法是在解法一的基础上进行改进,先根据矩阵的特性搜寻出target所在的行,然后使用二分对那一行的所有数字进行搜寻

**注意:**时间复杂度为O(long2m)

解法三:

在解法二的基础上进一步改进,使用两次二分搜寻,第一次找出目标值所在的行,第二次在那一行使用二分查找出目标值

**注意:**这样的做法的时间复杂度为O(long2m)

代码

解法一:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        
        int n = matrix.size(), m = matrix[0].size();
    
        int i = 0, j = m - 1;
        while(true)
        {
            if(i >= n || j < 0) return false;

            if(matrix[i][j] == target) return true;

            if(matrix[i][j] < target) i ++;
            else if(matrix[i][j] > target) j -- ;
        }
            
        return false;

    }
};

解法二:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        
        int n = matrix.size(), m = matrix[0].size();
    
        int i = 0, j = m - 1;
        while(i < n && matrix[i][j] < target) i ++;
        
        if(i >= n) return false;
        if(matrix[i][j] == target) return true;
        
        // 对本行进行二分搜寻
        int left = 0, right = m - 1;
        while(left < right)
        {
            int mid = (left + right) / 2;
            if(matrix[i][mid] >= target) right = mid;
            else left = mid + 1;
        }
        if(matrix[i][left] != target) return false;
        return true;

    }
};

解法三:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        
        int n = matrix.size(), m = matrix[0].size();
    
       // 对本行进行二分搜寻
        int left = 0, right = n - 1;
        while(left < right)
        {
            int mid = (left + right) / 2;
            if(matrix[left][0] <= target && matrix[mid][m - 1] >= target) right = mid;
            else left = mid + 1;
        }

        int row = left;

        // 对本行进行二分搜寻
        left = 0, right = m - 1;
        while(left < right)
        {
            int mid = (left + right) / 2;
            if(matrix[row][mid] >= target) right = mid;
            else left = mid + 1;
        }
        if(matrix[row][left] != target) return false;
        return true;

    }
};