74. Search a 2D Matrix

74. 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.

解析

  • 主要是注意边界条件为空的情况,然后就是两个for循环的bug,用while (i>=0&&j<m)即可。
  • 其他思路:1.将二维数组按行展开的话,就是一个排序的一维数组,因此通过一维数组的二分查找很容易得到答案。
  • 2.先通过二分查找元素所在的行,再在所在行通过二分查找元素。

  • 复杂度:O(m+n)

//74. Search a 2D Matrix
class Solution_74 {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {

        if (matrix.empty()||matrix[0].empty())
        {
            return false;
        }

        int n = matrix.size();
        int m = matrix[0].size();

        /*for (int i = n-1; i >= 0; ) //bug:导致每次循环边界条件判断有问题
        {
        for (int j = 0; j < m;)
        {*/
        int i = n - 1, j = 0;
        while (i>=0&&j<m)
        {
            {
                if (matrix[i][j]==target)
                {
                    return true;
                }
                else if (matrix[i][j]<target)
                {
                    j++;
                }
                else
                {
                    --i;
                }
            }
        }

        return false;
    }
};

lintcode

  • 复杂度O(log(m)+log(n))=O(log(m*n))
  • 也可以看成一维数组,直接对m*n个元素进行二分查找
class Solution_28 {
public:
    /**
    * @param matrix: matrix, a list of lists of integers
    * @param target: An integer
    * @return: a boolean, indicate whether matrix contains target
    */
    bool searchMatrix1(vector<vector<int>> &matrix, int target) {
        // write your code 
        if (matrix.empty())
            return false;
        int row = matrix.size();
        int col = matrix[0].size();

        for (int i = row - 1; i >= 0;) {
            /* code */
            for (int j = 0; j<col;)
            {
                if (matrix[i][j] == target)
                    return true;
                else if (matrix[i][j]<target)
                    j++;
                else
                    i--;
            }
        }
        return false;
    }

    bool binary_search(vector<int>& vec, int target)
    {
        int low = 0;
        int high = vec.size() - 1;
        while (low <= high)
        {
            int mid = low + (high - low) / 2;
            if (vec[mid] == target)
                return true;
            else if (vec[mid]>target)
                high = mid - 1;
            else
                low = mid + 1;
        }
        return false;
    }

    bool searchMatrix(vector<vector<int>> &matrix, int target)
    {
        if (matrix.empty())
            return false;
        int low = 0;
        int high = matrix.size() - 1; //二分找对应行

        int mid = (high + low + 1) / 2;
        while (low < high)
        {
            
            if (matrix[mid][0] == target)
                return true;
            else if (matrix[mid][0]>target)
                high = mid - 1;
            else
                low = mid;

            mid = (high + low + 1) / 2;
        }

        //对应low行二分查找列
        return binary_search(matrix[mid], target);

    }

};
  • 一次二分查找

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

参考代码

    原文作者:ranjiewen
    原文地址: https://www.cnblogs.com/ranjiewen/p/8677036.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞