1. 程式人生 > >【LeetCode & 劍指offer刷題】矩陣題1:4 有序矩陣中的查詢( 74. Search a 2D Matrix )(系列)

【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 ;            } };