Search a 2D Matrix leetcode java


題目

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.

For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

Given target = 3, return true.


題解:

雖然本題看似是矩陣問題,但是本着搜索題目關鍵字為第一步的原則,可以找到:each row are sorted,每一行按照順序也是sorted。同時也是數組保存。

但是本題的難點就是如何將2D矩陣轉換成1D,然后利用二分查找法來解決問題。轉換的重點就在於每個點的位置,在矩陣表示中,我們習慣用(i,j)來表示一個點,所以這就有礙於我們使用low high mid來指向需要的位置。為了解決問題,第一步就是需要將這個矩陣按照順序拉成一條線。

像題中的例子我可以將其轉化為:

position: 0   1   2   3   4   5   6   7   8   9   10   11   

values:   1   3   5   7   10 11 16 20  23 30  34  50

row:       0   0   0   0   1   1   1   1   2   2    2    2

column:  0   1   2   3   0   1   2   3   0   1    2    3

 

其中:行數rows=3,列數columns=4

 

如上,這個就是將2D矩陣轉化成1行數組的對應表。所以對於二分查找法的初始值為:low=0,high=rows*columns-1(總共數值的個數,因為從0開始所以減1)。而為了能夠方便在given 2D matrix找到需要比對的值,我們還是需要確定行數和列數,通過上表可以看出,行數是position/columns,而列數是position%columns, 這樣一來,就能很容易的在原矩陣中定位到所需要的值。剩下其他的解題思路,就與二分查找法一模一樣了。

時間復雜度O(log(rows*columns))

 

代碼如下:

 1      public  boolean searchMatrix( int[][] matrix,  int target) {
 2          if(matrix.length==0||matrix[0].length==0||matrix== null)
 3              return  false;
 4             
 5          int rows = matrix.length;
 6          int cols = matrix[0].length;
 7         
 8          int low = 0;
 9          int high = rows*cols-1;
10         
11          while(low<=high){
12              int mid = (low+high)/2;
13              int midValue = matrix[mid/cols][mid%cols];
14              if(midValue == target)
15                  return  true;
16              else  if(midValue < target)
17                 low = mid+1;
18              else
19                 high = mid-1;
20         }
21          return  false;
22     }

 

同時,也有另外一個解決該題的方法,就是利用兩次二分查找法。因為所給矩陣第一列也是升序排列的,所以可以先對第一列進行二分查找,鎖定該元素所在行數,然后再對列進行二分查找,即可判斷target是否存在。這個的算法時間復雜度是O(log(rows)+log(columns))。

代碼如下:

 1      public  boolean searchMatrix( int[][] matrix,  int target) {  
 2          if(matrix ==  null || matrix.length==0 || matrix[0].length==0)  
 3              return  false;  
 4          int low = 0;  
 5          int high = matrix.length-1;  
 6          while(low<=high){  
 7              int mid = (low+high)/2;  
 8              if(matrix[mid][0] == target)
 9                  return  true;  
10              else  if(matrix[mid][0] > target)  
11                 high = mid-1; 
12              else
13                 low = mid+1;  
14         }
15         
16          int row = high; //當從while中跳出時,low指向的值肯定比target大,而high指向的值肯定比target小
17         
18          if(row<0)  
19              return  false
20             
21         low = 0;  
22         high = matrix[0].length-1;  
23          while(low<=high){  
24              int mid = (low+high)/2;  
25              if(matrix[row][mid] == target)
26                  return  true;  
27              else  if(matrix[row][mid] > target)  
28                 high = mid-1;
29              else 
30                 low = mid+1;  
31         }     
32          return  false;  
33     } 

 

Reference:

http://www.programcreek.com/2013/01/leetcode-search-a-2d-matrix-java/

http://blog.csdn.net/linhuanmars/article/details/24216235


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM