רכיב חיפוש במטריצה ​​ממוינת

נתון מטריצה ​​ממוינת יחד עם [][] בגודל n × m ומספר שלם x לקבוע אם x קיים במטריצה.
המטריצה ​​ממוינת באופן הבא:

  • כל שורה ממוינת בסדר הולך וגדל.
  • האלמנט הראשון של כל שורה גדול או שווה לרכיב האחרון של השורה הקודמת
    (כלומר mat[i][0] ≥ mat[i−1][m−1] עבור כל 1 ≤ i < n).

דוגמאות:

קֶלֶט: x = 14 מחצלת[][] = [[ 1 5 9]
[14 20 21]
[30 34 43]]
תְפוּקָה: נָכוֹן
הֶסבֵּר: הערך 14 קיים בשורה השנייה העמודה הראשונה של המטריצה.

קֶלֶט: x = 42 מחצלת[][] = [[ 1 5 9 11]
[14 20 21 26]
[30 34 43 50]]
תְפוּקָה: שֶׁקֶר
הֶסבֵּר: הערך 42 לא מופיע במטריצה.

תוכן עניינים

[גישה נאיבית] השוואה עם כל האלמנטים - O(n × m) זמן ו-O(1) מרחב

הרעיון הוא לחזור על כל המטריצה ​​[][] ולהשוות כל אלמנט עם x. אם אלמנט מתאים ל-x נחזיר true. אחרת בסוף המעבר נחזיר שקר.

C++
   #include          #include         using     namespace     std  ;   bool     searchMatrix  (  vector   <  vector   <  int  >>&     mat       int     x  )     {      int     n     =     mat  .  size  ();      int     m     =     mat  [  0  ].  size  ();      // traverse every element in the matrix      for     (  int     i     =     0  ;     i      <     n  ;     i  ++  )     {      for     (  int     j     =     0  ;     j      <     m  ;     j  ++  )     {      if     (  mat  [  i  ][  j  ]     ==     x  )      return     true  ;      }      }      return     false  ;   }   int     main  ()     {      vector   <  vector   <  int  >>     mat     =     {      {  1       5       9  }      {  14       20       21  }      {  30       34       43  }      };      int     x     =     14  ;      cout      < <     (  searchMatrix  (  mat       x  )     ?     'true'     :     'false'  )      < <     endl  ;   }   
Java
   class   GfG     {      public     static     boolean     searchMatrix  (  int  [][]     mat       int     x  )     {      int     n     =     mat  .  length  ;      int     m     =     mat  [  0  ]  .  length  ;      // traverse every element in the matrix      for     (  int     i     =     0  ;     i      <     n  ;     i  ++  )     {      for     (  int     j     =     0  ;     j      <     m  ;     j  ++  )     {      if     (  mat  [  i  ][  j  ]     ==     x  )      return     true  ;      }      }      return     false  ;      }      public     static     void     main  (  String  []     args  )     {      int  [][]     mat     =     {      {  1       5       9  }      {  14       20       21  }      {  30       34       43  }      };      int     x     =     14  ;      System  .  out  .  println  (  searchMatrix  (  mat       x  )     ?     'true'     :     'false'  );      }   }   
Python
   def   searchMatrix  (  mat     x  ):   n   =   len  (  mat  )   m   =   len  (  mat  [  0  ])   # traverse every element in the matrix   for   i   in   range  (  n  ):   for   j   in   range  (  m  ):   if   mat  [  i  ][  j  ]   ==   x  :   return   True   return   False   if   __name__   ==   '__main__'  :   mat   =   [   [  1     5     9  ]   [  14     20     21  ]   [  30     34     43  ]   ]   x   =   14   print  (  'true'   if   searchMatrix  (  mat     x  )   else   'false'  )   
C#
   using     System  ;   class     GfG     {      public     static     bool     searchMatrix  (  int  [][]     mat       int     x  )     {      int     n     =     mat  .  Length  ;      int     m     =     mat  [  0  ].  Length  ;      // traverse every element in the matrix      for     (  int     i     =     0  ;     i      <     n  ;     i  ++  )     {      for     (  int     j     =     0  ;     j      <     m  ;     j  ++  )     {      if     (  mat  [  i  ][  j  ]     ==     x  )      return     true  ;      }      }      return     false  ;      }      public     static     void     Main  (  string  []     args  )     {      int  [][]     mat     =     new     int  [][]     {      new     int  []     {  1       5       9  }      new     int  []     {  14       20       21  }      new     int  []     {  30       34       43  }      };      int     x     =     14  ;      Console  .  WriteLine  (  searchMatrix  (  mat       x  )     ?     'true'     :     'false'  );      }   }   
JavaScript
   function     searchMatrix  (  mat       x  )     {      let     n     =     mat  .  length  ;      let     m     =     mat  [  0  ].  length  ;      // traverse every element in the matrix      for     (  let     i     =     0  ;     i      <     n  ;     i  ++  )     {      for     (  let     j     =     0  ;     j      <     m  ;     j  ++  )     {      if     (  mat  [  i  ][  j  ]     ===     x  )      return     true  ;      }      }      return     false  ;   }   // Driver Code   let     mat     =     [      [  1       5       9  ]      [  14       20       21  ]      [  30       34       43  ]   ];   let     x     =     14  ;   console  .  log  (  searchMatrix  (  mat       x  )     ?     'true'     :     'false'  );   

תְפוּקָה
true  

[גישה טובה יותר] שימוש בחיפוש בינארי פעמיים - O(log n + log m) זמן ו-O(1) רווח

ראשית אנו מאתרים את השורה שבה יכול להיות יעד x באמצעות חיפוש בינארי ולאחר מכן אנו מיישמים שוב חיפוש בינארי בתוך אותה שורה. כדי למצוא את השורה הנכונה אנו מבצעים חיפוש בינארי על האלמנטים הראשונים של השורה האמצעית.

יישום צעד אחר צעד:

=> התחל עם נמוך = 0 וגבוה = n - 1.
=> אם x קטן מהרכיב הראשון בשורה האמצעית (a[mid][0]) אז x יהיה קטן יותר מכל האלמנטים בשורות >= אמצע אז עדכן גבוה = אמצע - 1.
=> אם x גדול מהאלמנט הראשון בשורה האמצעית (a[mid][0]) אז x יהיה גדול מכל האלמנטים בשורות < mid so store the current mid row and update low = mid + 1.

לאחר שמצאנו את השורה הנכונה נוכל להחיל חיפוש בינארי בתוך אותה שורה כדי לחפש את רכיב המטרה x.

C++
   #include          #include         using     namespace     std  ;   // function to binary search for x in arr[]   bool     search  (  vector   <  int  >     &  arr       int     x  )     {      int     lo     =     0       hi     =     arr  .  size  ()     -     1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      if     (  x     ==     arr  [  mid  ])      return     true  ;      if     (  x      <     arr  [  mid  ])      hi     =     mid     -     1  ;      else      lo     =     mid     +     1  ;      }      return     false  ;   }   // function to search element x in fully    // sorted matrix   bool     searchMatrix  (  vector   <  vector   <  int  >>     &  mat       int     x  )     {      int     n     =     mat  .  size  ()     m     =     mat  [  0  ].  size  ();      int     lo     =     0       hi     =     n     -     1  ;      int     row     =     -1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      // if the first element of mid row is equal to x      // return true      if     (  x     ==     mat  [  mid  ][  0  ])      return     true  ;          // if x is greater than first element of mid row      // store the mid row and search in lower half      if     (  x     >     mat  [  mid  ][  0  ])     {      row     =     mid  ;      lo     =     mid     +     1  ;      }          // if x is smaller than first element of mid row      // search in upper half      else      hi     =     mid     -     1  ;      }          // if x is smaller than all elements of mat[][]      if     (  row     ==     -1  )      return     false  ;      return     search  (  mat  [  row  ]     x  );   }   int     main  ()     {      vector   <  vector   <  int  >>     mat     =     {{  1       5       9  }     {  14       20       21  }     {  30       34       43  }};      int     x     =     14  ;      if     (  searchMatrix  (  mat       x  ))      cout      < <     'true'  ;      else      cout      < <     'false'  ;      return     0  ;   }   
Java
   class   GfG     {          // function to binary search for x in arr[]      static     boolean     search  (  int  []     arr       int     x  )     {      int     lo     =     0       hi     =     arr  .  length     -     1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      if     (  x     ==     arr  [  mid  ]  )      return     true  ;      if     (  x      <     arr  [  mid  ]  )      hi     =     mid     -     1  ;      else      lo     =     mid     +     1  ;      }      return     false  ;      }          // function to search element x in fully       // sorted matrix      static     boolean     searchMatrix  (  int  [][]     mat       int     x  )     {      int     n     =     mat  .  length       m     =     mat  [  0  ]  .  length  ;      int     lo     =     0       hi     =     n     -     1  ;      int     row     =     -  1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      // if the first element of mid row is equal to x      // return true      if     (  x     ==     mat  [  mid  ][  0  ]  )      return     true  ;      // if x is greater than first element of mid row      // store the mid row and search in lower half      if     (  x     >     mat  [  mid  ][  0  ]  )     {      row     =     mid  ;      lo     =     mid     +     1  ;      }      // if x is smaller than first element of mid row      // search in upper half      else      hi     =     mid     -     1  ;      }      // if x is smaller than all elements of mat[][]      if     (  row     ==     -  1  )      return     false  ;      return     search  (  mat  [  row  ]       x  );      }      public     static     void     main  (  String  []     args  )     {      int  [][]     mat     =     {      {  1       5       9  }      {  14       20       21  }      {  30       34       43  }      };      int     x     =     14  ;      if     (  searchMatrix  (  mat       x  ))      System  .  out  .  println  (  'true'  );      else      System  .  out  .  println  (  'false'  );      }   }   
Python
   # function to binary search for x in arr[]   def   search  (  arr     x  ):   lo   =   0   hi   =   len  (  arr  )   -   1   while   lo    <=   hi  :   mid   =   (  lo   +   hi  )   //   2   if   x   ==   arr  [  mid  ]:   return   True   if   x    <   arr  [  mid  ]:   hi   =   mid   -   1   else  :   lo   =   mid   +   1   return   False   # function to search element x in fully    # sorted matrix   def   searchMatrix  (  mat     x  ):   n   =   len  (  mat  )   m   =   len  (  mat  [  0  ])   lo   =   0   hi   =   n   -   1   row   =   -  1   while   lo    <=   hi  :   mid   =   (  lo   +   hi  )   //   2   # if the first element of mid row is equal to x   # return true   if   x   ==   mat  [  mid  ][  0  ]:   return   True   # if x is greater than first element of mid row   # store the mid row and search in lower half   if   x   >   mat  [  mid  ][  0  ]:   row   =   mid   lo   =   mid   +   1   # if x is smaller than first element of mid row   # search in upper half   else  :   hi   =   mid   -   1   # if x is smaller than all elements of mat[][]   if   row   ==   -  1  :   return   False   return   search  (  mat  [  row  ]   x  )   if   __name__   ==   '__main__'  :   mat   =   [[  1     5     9  ]   [  14     20     21  ]   [  30     34     43  ]]   x   =   14   if   searchMatrix  (  mat     x  ):   print  (  'true'  )   else  :   print  (  'false'  )   
C#
   using     System  ;   class     GfG     {          // function to binary search for x in arr[]      static     bool     Search  (  int  []     arr       int     x  )     {      int     lo     =     0       hi     =     arr  .  Length     -     1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      if     (  x     ==     arr  [  mid  ])      return     true  ;      if     (  x      <     arr  [  mid  ])      hi     =     mid     -     1  ;      else      lo     =     mid     +     1  ;      }      return     false  ;      }          // function to search element x in fully       // sorted matrix      static     bool     SearchMatrix  (  int  [][]     mat       int     x  )     {      int     n     =     mat  .  Length       m     =     mat  [  0  ].  Length  ;      int     lo     =     0       hi     =     n     -     1  ;      int     row     =     -  1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      // if the first element of mid row is equal to x      // return true      if     (  x     ==     mat  [  mid  ][  0  ])      return     true  ;      // if x is greater than first element of mid row      // store the mid row and search in lower half      if     (  x     >     mat  [  mid  ][  0  ])     {      row     =     mid  ;      lo     =     mid     +     1  ;      }      // if x is smaller than first element of mid row      // search in upper half      else      hi     =     mid     -     1  ;      }      // if x is smaller than all elements of mat[][]      if     (  row     ==     -  1  )      return     false  ;      return     Search  (  mat  [  row  ]     x  );      }      static     void     Main  (  string  []     args  )     {      int  [][]     mat     =     new     int  [][]     {      new     int  []     {  1       5       9  }      new     int  []     {  14       20       21  }      new     int  []     {  30       34       43  }      };      int     x     =     14  ;      if     (  SearchMatrix  (  mat       x  ))      Console  .  WriteLine  (  'true'  );      else      Console  .  WriteLine  (  'false'  );      }   }   
JavaScript
   // function to binary search for x in arr[]   function     search  (  arr       x  )     {      let     lo     =     0       hi     =     arr  .  length     -     1  ;      while     (  lo      <=     hi  )     {      let     mid     =     Math  .  floor  ((  lo     +     hi  )     /     2  );      if     (  x     ===     arr  [  mid  ])      return     true  ;      if     (  x      <     arr  [  mid  ])      hi     =     mid     -     1  ;      else      lo     =     mid     +     1  ;      }      return     false  ;   }   // function to search element x in fully    // sorted matrix   function     searchMatrix  (  mat       x  )     {      let     n     =     mat  .  length       m     =     mat  [  0  ].  length  ;      let     lo     =     0       hi     =     n     -     1  ;      let     row     =     -  1  ;      while     (  lo      <=     hi  )     {      let     mid     =     Math  .  floor  ((  lo     +     hi  )     /     2  );      // if the first element of mid row is equal to x      // return true      if     (  x     ===     mat  [  mid  ][  0  ])      return     true  ;      // if x is greater than first element of mid row      // store the mid row and search in lower half      if     (  x     >     mat  [  mid  ][  0  ])     {      row     =     mid  ;      lo     =     mid     +     1  ;      }      // if x is smaller than first element of mid row      // search in upper half      else      hi     =     mid     -     1  ;      }      // if x is smaller than all elements of mat[][]      if     (  row     ===     -  1  )      return     false  ;      return     search  (  mat  [  row  ]     x  );   }   // Driver code   const     mat     =     [      [  1       5       9  ]      [  14       20       21  ]      [  30       34       43  ]   ];   const     x     =     14  ;   if     (  searchMatrix  (  mat       x  ))      console  .  log  (  'true'  );   else      console  .  log  (  'false'  );   

תְפוּקָה
true 

[גישה צפויה] שימוש בחיפוש בינארי פעם אחת - O(log(n × m)) ו-O(1) רווח

הרעיון הוא לשקול את המטריצה ​​הנתונה כמערך 1D ולהחיל רק חיפוש בינארי אחד.
לדוגמה עבור מטריצה ​​בגודל n x m ונוכל לראות אותה כמערך 1D בגודל n*m אז האינדקס הראשון יהיה 0 והאינדקס האחרון יהיה n*m-1. אז אנחנו צריכים לעשות חיפוש בינארי מנמוך = 0 עד גבוה = (n*m-1).

כיצד למצוא את האלמנט במטריצה ​​דו-ממדית המתאים לאינדקס = אמצע?

מכיוון שלכל שורה של מחצלת[][] יהיו m אלמנטים כדי שנוכל למצוא את שׁוּרָה של האלמנט as (אמצע / מ') ואת עַמוּדָה של האלמנט as (אמצע % m) . לאחר מכן נוכל להשוות את x עם arr[mid/m][mid%m] עבור כל אמצע ולהשלים את החיפוש הבינארי שלנו.

C++
   #include          #include         using     namespace     std  ;   bool     searchMatrix  (  vector   <  vector   <  int  >>&     mat       int     x  )     {      int     n     =     mat  .  size  ()     m     =     mat  [  0  ].  size  ();      int     lo     =     0       hi     =     n     *     m     -     1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;          // find row and column of element at mid index      int     row     =     mid     /     m  ;      int     col     =     mid     %     m  ;          // if x is found return true      if     (  mat  [  row  ][  col  ]     ==     x  )         return     true  ;          // if x is greater than mat[row][col] search       // in right half      if     (  mat  [  row  ][  col  ]      <     x  )         lo     =     mid     +     1  ;          // if x is less than mat[row][col] search       // in left half      else         hi     =     mid     -     1  ;      }      return     false  ;   }   int     main  ()     {      vector   <  vector   <  int  >>     mat     =     {{  1       5       9  }         {  14       20       21  }         {  30       34       43  }};      int     x     =     14  ;      if     (  searchMatrix  (  mat       x  ))      cout      < <     'true'  ;      else      cout      < <     'false'  ;      return     0  ;   }   
Java
   class   GfG     {      static     boolean     searchMatrix  (  int  [][]     mat       int     x  )     {      int     n     =     mat  .  length       m     =     mat  [  0  ]  .  length  ;      int     lo     =     0       hi     =     n     *     m     -     1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      // find row and column of element at mid index      int     row     =     mid     /     m  ;      int     col     =     mid     %     m  ;      // if x is found return true      if     (  mat  [  row  ][  col  ]     ==     x  )      return     true  ;      // if x is greater than mat[row][col] search       // in right half      if     (  mat  [  row  ][  col  ]      <     x  )      lo     =     mid     +     1  ;      // if x is less than mat[row][col] search       // in left half      else      hi     =     mid     -     1  ;      }      return     false  ;      }      public     static     void     main  (  String  []     args  )     {      int  [][]     mat     =     {{  1       5       9  }         {  14       20       21  }         {  30       34       43  }};      int     x     =     14  ;      if     (  searchMatrix  (  mat       x  ))      System  .  out  .  println  (  'true'  );      else      System  .  out  .  println  (  'false'  );      }   }   
Python
   def   searchMatrix  (  mat     x  ):   n   =   len  (  mat  )   m   =   len  (  mat  [  0  ])   lo     hi   =   0     n   *   m   -   1   while   lo    <=   hi  :   mid   =   (  lo   +   hi  )   //   2   # find row and column of element at mid index   row   =   mid   //   m   col   =   mid   %   m   # if x is found return true   if   mat  [  row  ][  col  ]   ==   x  :   return   True   # if x is greater than mat[row][col] search    # in right half   if   mat  [  row  ][  col  ]    <   x  :   lo   =   mid   +   1   # if x is less than mat[row][col] search    # in left half   else  :   hi   =   mid   -   1   return   False   if   __name__   ==   '__main__'  :   mat   =   [[  1     5     9  ]   [  14     20     21  ]   [  30     34     43  ]]   x   =   14   if   searchMatrix  (  mat     x  ):   print  (  'true'  )   else  :   print  (  'false'  )   
C#
   using     System  ;   class     GfG     {          // function to search for x in the matrix       // using binary search      static     bool     searchMatrix  (  int  []     mat       int     x  )     {      int     n     =     mat  .  GetLength  (  0  )     m     =     mat  .  GetLength  (  1  );      int     lo     =     0       hi     =     n     *     m     -     1  ;      while     (  lo      <=     hi  )     {      int     mid     =     (  lo     +     hi  )     /     2  ;      // find row and column of element at mid index      int     row     =     mid     /     m  ;      int     col     =     mid     %     m  ;      // if x is found return true      if     (  mat  [  row       col  ]     ==     x  )      return     true  ;      // if x is greater than mat[row col] search      // in right half      if     (  mat  [  row       col  ]      <     x  )      lo     =     mid     +     1  ;      // if x is less than mat[row col] search       // in left half      else      hi     =     mid     -     1  ;      }      return     false  ;      }      static     void     Main  ()     {      int  []     mat     =     {     {     1       5       9     }     {     14       20       21     }     {     30       34       43     }     };      int     x     =     14  ;      if     (  searchMatrix  (  mat       x  ))      Console  .  WriteLine  (  'true'  );      else      Console  .  WriteLine  (  'false'  );      }   }   
JavaScript
   function     searchMatrix  (  mat       x  )     {      let     n     =     mat  .  length       m     =     mat  [  0  ].  length  ;      let     lo     =     0       hi     =     n     *     m     -     1  ;      while     (  lo      <=     hi  )     {      let     mid     =     Math  .  floor  ((  lo     +     hi  )     /     2  );      // find row and column of element at mid index      let     row     =     Math  .  floor  (  mid     /     m  );      let     col     =     mid     %     m  ;      // if x is found return true      if     (  mat  [  row  ][  col  ]     ===     x  )      return     true  ;      // if x is greater than mat[row][col] search       // in right half      if     (  mat  [  row  ][  col  ]      <     x  )      lo     =     mid     +     1  ;      // if x is less than mat[row][col] search       // in left half      else      hi     =     mid     -     1  ;      }      return     false  ;   }   // Driver Code   let     mat     =     [[  1       5       9  ]     [  14       20       21  ]     [  30       34       43  ]];   let     x     =     14  ;   if     (  searchMatrix  (  mat       x  ))      console  .  log  (  'true'  );   else      console  .  log  (  'false'  );   

תְפוּקָה
true 
צור חידון