zoukankan      html  css  js  c++  java
  • 【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;
          
        }
    };
     
     
  • 相关阅读:
    bzoj2733 永无乡 平衡树按秩合并
    bzoj2752 高速公路 线段树
    bzoj1052 覆盖问题 二分答案 dfs
    bzoj1584 打扫卫生 dp
    bzoj1854 游戏 二分图
    bzoj3316 JC loves Mkk 二分答案 单调队列
    bzoj3643 Phi的反函数 数学 搜索
    有一种恐怖,叫大爆搜
    BZOJ3566 概率充电器 概率dp
    一些奇奇怪怪的过题思路
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10225002.html
Copyright © 2011-2022 走看看