题目:
搜索二维矩阵
写出一个高效的算法来搜索 m × n矩阵中的值。
这个矩阵具有以下特性:
- 每行中的整数从左到右是排序的。
- 每行的第一个数大于上一行的最后一个整数。
样例
考虑下列矩阵:
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
给出 target = 3,返回 true
挑战
View Code
View Code
O(log(n) + log(m)) 时间复杂度
解题:
更新730
直接二分查找
public boolean searchMatrix(int[][] A, int target) { // write your code here if(A == null || A.length == 0 || A[0].length ==0) return false; int row = A.length; int col = A[0].length; int len = row * col; int left = 0; int right = len-1 ;// while(left <= right){ int mid = left + (right - left)/2; int x = A[mid/col][mid%col]; if(x==target){ return true; }else if(x>target){ right = mid-1; }else{ left = mid+1; } } return false; }
1.最简单的方法就是遍历整个矩阵,时间复杂度:O(log(mn)),这个应该等于O(long(n)+log(m))
2.题目给的矩阵是有序矩阵,先按照最后一列二分查找,确定列,再二分确定行,时间复杂度O(log(m)) + O(log(n)),哦,哦,哦,题目的挑战可能是搞错了。。。
1.暴力
Java程序:
public class Solution { /** * @param matrix, a list of lists of integers * @param target, an integer * @return a boolean, indicate whether matrix contains target */ public boolean searchMatrix(int[][] matrix, int target) { // write your code here 二分查找 if(matrix==null) return false; int m = matrix.length; if(m==0) return false; int n = matrix[0].length; for(int i=0;i<m;i++){ for(int j=0;j<n;j++) if(matrix[i][j]==target) return true; } return false; } }
总耗时: 1571 ms
Python程序:
class Solution: """ @param matrix, a list of lists of integers @param target, an integer @return a boolean, indicate whether matrix contains target """ def searchMatrix(self, matrix, target): # write your code here if matrix==None: return False m = len(matrix) if m==0: return False n = len(matrix[0]) for i in range(m): for j in range(n): if matrix[i][j]==target: return True return False
总耗时: 260 ms
2.二分法
利用二分思想程序,先求所在的行,再求所在的列,搞了好久,边界错了好多次。。。
Java程序:
public class Solution { /** * @param matrix, a list of lists of integers * @param target, an integer * @return a boolean, indicate whether matrix contains target */ public boolean searchMatrix(int[][] matrix, int target) { // write your code here 二分查找 if(matrix==null) return false; int nrow = matrix.length; if(nrow==0) return false; int ncol = matrix[0].length; // 行 nrow //列 ncol int row = rowbinSearch(matrix,0,nrow-1,ncol,target); int col = colbinSearch(matrix,0,ncol-1,row,target); if(col!=-1) return true; return false; } // 找出所在的行 private int rowbinSearch(int[][] matrix,int left,int right,int ncol,int target){ //矩阵matrix ,二分的两个界:left、right,矩阵的最后一列ncol,目标值target int median = (left + right)/2; int row = median; if(left==right) return left; if(matrix[left][ncol-1]<=target && matrix[left+1][ncol-1]>target) return left; if(matrix[median][ncol-1]>= target && matrix[median][0]<=target) return median; if(matrix[median][ncol-1]<target) row = rowbinSearch(matrix,median+1,right,ncol,target); else row = rowbinSearch(matrix,left,median-1,ncol,target); return row; } // 找出所在的列 private int colbinSearch(int[][] matrix,int left,int right,int row,int target){ //矩阵matrix ,二分的两个界:left、right,target所在的行: row,目标值target int median = (left + right)/2; int col = median; if(left>right) return -1; if(left==right && matrix[row][left]!=target) return -1; if(matrix[row][median]==target) return median; if(matrix[row][median]<target) col = colbinSearch(matrix,median+1,right,row,target); else col = colbinSearch(matrix,left,median-1,row,target); return col; } }
总耗时: 2246 ms
3.暴力2.0
九章算法中看到的,给的Java程序利用二分法,但是没有用递归,给的Python程序,没有明显的用到矩阵变量,但是通过商和余数确定所在的行和列
Python程序:
class Solution: """ @param matrix, a list of lists of integers @param target, an integer @return a boolean, indicate whether matrix contains target """ def searchMatrix(self, matrix, target): # write your code here if len(matrix)==0: return False n,m=len(matrix),len(matrix[0]) start,end = 0,n*m-1 while start+1< end: mid = (start + end)/2 x,y = mid/m,mid%m if matrix[x][y]<target: start = mid else: end = mid x,y = start/m,start%m if matrix[x][y]==target: return True x,y = end/m,end%m if matrix[x][y] == target: return True return False