[LeetCode]28. Search a 2D Matrix矩阵查找

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

Given target = 3, return true.

解法1:据题意,矩阵以行主序展开到一维后就是一个排序数组,因此可以用二分查找,将当前查找index转换为二维坐标即可。

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

        int left = 0, right = m * n - 1;
        while (left <= right)
        {
            int mid = (left + right) >> 1;
            int i = mid / n, j = mid % n;
            if (target == matrix[i][j])
                return true;
            else if (target < matrix[i][j])
                right = mid - 1;
            else
                left = mid + 1;
        }
        return false;
    }
};

解法2:可以根据target和每一行第一个数的比较进行二分查找,先确定target所在目标行:若target==nums[i][0],直接返回true;若target>nums[i][0],则target必在[i,m)的那几行;否则target在[0,i)的那几行。最后可以确定target具体在哪一行;在确定了具体的行后,再对该行进行二分查找,确定target具体位置。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if (matrix.empty() || matrix[0].empty())
            return false;
        if(target < matrix.front().front() || target > matrix.back().back())
            return false;
        int m = matrix.size();
        int n = matrix[0].size();

        int above = 0, below = m - 1;
        while(above <= below)
        {
            int mid = (above + below) >> 1;
            if(target == matrix[mid][0])
                return true;
            else if(target < matrix[mid][0])
                below = mid - 1;
            else
                above = mid + 1; //虽然实际上此时target可能恰好mid这行,但是above还是必须设置为mid+1,否则形成死循环
        }
        //注意不能使用matrix[above],因为target>matrix[mid][0]时target有可能恰好在matrix[mid]中,此时above=mid+1是不行的
        return binarySearch(matrix[below], target); 
    }
private:
    bool binarySearch(const vector<int>& nums, int key)
    {
        int n = nums.size();
        int left = 0, right = n - 1;
        while (left <= right)
        {
            int mid = (left + right) >> 1;
            if (key == nums[mid])
                return true;
            else if (key < nums[mid])
                right = mid - 1;
            else
                left = mid + 1;
        }
        return false;
    }
};

如果target是和matrix[i][n-1]比较来确定target所在行的话,则上面代码注释地方恰好要使用matrix[above]了:

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if (matrix.empty() || matrix[0].empty())
            return false;
        if(target < matrix.front().front() || target > matrix.back().back()) //处理矩阵只有一个元素的情况
            return false;
        int m = matrix.size();
        int n = matrix[0].size();

        int above = 0, below = m - 1;
        while(above <= below)
        {
            int mid = (above + below) >> 1;
            if(target == matrix[mid][n - 1])
                return true;
            else if(target < matrix[mid][n - 1])
                below = mid - 1; //虽然实际上此时target可能恰好mid这行,但是below还是必须设置为mid-1,否则形成死循环
            else
                above = mid + 1; 
        }
        //注意不能使用matrix[below],因为target>matrix[mid][0]时target有可能恰好在matrix[mid]中,此时below=mid-1是不行的
        return binarySearch(matrix[above], target); 
    }
private:
    bool binarySearch(const vector<int>& nums, int key)
    {
        int n = nums.size();
        int left = 0, right = n - 1;
        while (left <= right)
        {
            int mid = (left + right) >> 1;
            if (key == nums[mid])
                return true;
            else if (key < nums[mid])
                right = mid - 1;
            else
                left = mid + 1;
        }
        return false;
    }
};
原文地址:https://www.cnblogs.com/aprilcheny/p/4884760.html