【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 i n 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 = 5 Output: 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 ;
      
    }
};
 
 

猜你喜欢

转载自www.cnblogs.com/wikiwen/p/10225002.html
今日推荐