【LeetCode & 剑指offer刷题】矩阵题1:4 有序矩阵中的查找( 74. Search a 2D Matrix )(系列)

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

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.
Example 1:
Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
Output: true
Example 2:
Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
Output: false
 
/*
问题:在有序矩阵中查找某数(每行增序,且行首元素大于前一行的行尾元素,蛇形有序)
方法:将二维数组看成一维数组用二分查找即可
*/
class Solution
{
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target)
    {
        if(matrix.empty() || matrix[0].empty()) return false;
           
        int rows = matrix.size();
        int cols = matrix[0].size();
        int left = 0, right = rows*cols - 1;
        while(left <= right)
        {
            int mid = (left+right) / 2;
            if(matrix[mid/cols][mid%cols] < target) left = mid+1;
            else if(matrix[mid/cols][mid%cols] > target) right = mid - 1;
            else return true;
        }
        return false;
    }
};
 
240. Search a 2D Matrix II
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 in ascending from left to right.
  • Integers in each column are sorted in ascending from top to bottom.
Consider the following matrix:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
Example 1:
Input: matrix, target = 5Output: true
Example 2:
Input: matrix, target = 20
Output: false
 
//问题:有序矩阵中查找(非蛇形有序)
/*
方法一:扫描行,每行进行二分查找
O(r*logc)
*/
 
class Solution
{
public:
    bool searchMatrix(vector<vector<int>>& a, int target)
    {
        if(a.empty() || a[0].empty()) return false; //若为空,则返回false
       
        int row = a.size(); //行数
        int col = a[0].size(); //列数
        for(int i = 0; i < row; i++)//遍历行,target要处于行首和行尾元素之间
        {
            if(a[i][0]<=target&&a[i][col-1] >= target) //不能放在for语句里,因为一旦条件不满足就跳出整个for循环了
            {
                if(a[i][0] == target || a[i][col-1] == target) return true;//如果行首或行尾元素等于target则返回true
               // cout<<"行数为"<<i<<endl;
                int left = 0, right = col-1; //遍历列,用二分查找算法查找
                while(left<=right)
                {
                    int mid = (left+right)/2;
                    if(a[i][mid] < target) left = mid+1;
                    else if(a[i][mid] > target) right = mid-1;
                    else return true;
                }              
            }
        }
        return false;
    }
};
/*
* 方法二:缩小范围,从左下角元素(该行中最小数,该列中最大数)开始比较(利用L型有序
* 过程:选取矩阵左下角元素,如果等于要查找的数,查找结束,
        如果小于目标数,找下一列,j++
        如果大于目标数,找上一行,i--
* 此方法效率较第一种高
O(r)或O(c)
*/
class Solution
{
public:
    bool searchMatrix(vector<vector<int>>& a, int target)
    {
        if(a.empty() || a[0].empty()) return false; //若为空,则返回false
      
        int row = a.size(); //行数
        int col = a[0].size(); //列数
      
        int i = row-1, j = 0;//从左下角元素开始比较
        while(i >= 0 && j <= col-1)
        {
            if(a[i][j] < target) //如果小于,则找下一列
                j++;
            else if(a[i][j] > target) //如果大于,找上一行
                i--;
            else
                return true;
        }
        return false;
      
    }
};
 
 

 

posted @ 2019-01-05 16:19  wikiwen  阅读(258)  评论(0编辑  收藏  举报