zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    CCNP路由实验(4) -- BGP
    CCNP路由实验(3) -- 路由控制
    CCNP路由实验(2) -- OSPF
    什么是依赖注入
    java中接口的定义与实现
    火炬之光模型导出(Unity载入火炬之光的模型)
    【创新培育项目】为什么要组队參加比赛?及如何寻找一个合适的选题?
    oracle中schema指的是什么?
    介绍自己上架的第一个游戏
    unity 打包资源及网络请求资源包
  • 原文地址:https://www.cnblogs.com/springfor/p/3857959.html
Copyright © 2011-2022 走看看