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, returntrue.
题意:在一个二维矩阵中,查询一个数是否存在。数组:1)每行从左到右从下到大排好;2)行首元素大于上一行的最后一个元素;
思路:常规思路:先遍历行找到元素所可能在的行,然后遍历列,判断是否在在该行中,时间复杂度O(n+m);二分查找版本一:是对常规思路的升级,先查找行 ,再查找列,但这时使用的查找的方法不是从头到尾的遍历,是二分查找,值得注意的是查找完行以后的返回值,时间复杂度O{logn+logm);二分查找版本二:因为矩阵数排列的特性,可以看成一个排列好的一维数组[0, n*m],可以针对整个二维矩阵进行二分查找,时间复杂还是O(log(n*m)),这里的难点是,如何将二维数组的下标和一维数组之间进行转换。
方法一:
1 class Solution { 2 public: 3 bool searchMatrix(vector<vector<int> > &matrix, int target) 4 { 5 int row = matrix.size(); 6 int col = matrix[0].size(); 7 int subRow = 0; 8 if (row == 0 || col == 0) return false; 9 10 //寻找行 11 if (matrix[row - 1][0] <= target) //最后一行,特殊处理 12 subRow = row - 1; 13 else 14 { 15 for (int i = 0; i<row - 1; ++i) 16 { 17 18 if ((matrix[i][0] <= target) && (matrix[i + 1][0]>target)) 19 { 20 subRow = i; 21 break; 22 } 23 } 24 } 25 26 //查找列 27 for (int j = 0; j<col; ++j) 28 { 29 if (matrix[subRow][j] == target) 30 return true; 31 } 32 return false; 33 } 34 };
方法二:如下:
1 // Two binary search 2 class Solution { 3 public: 4 bool searchMatrix(vector<vector<int> > &matrix, int target) 5 { 6 int row=matrix.size(); 7 int col=matrix[0].size(); 8 if (row==0 || col==0) return false; 9 if (target < matrix[0][0] || target > matrix[row-1][col-1]) return false; 10 11 //查找行 12 int lo = 0, hi = row - 1; 13 while (lo <= hi) 14 { 15 int mid = (lo+hi) / 2; 16 if (matrix[mid][0] == target) 17 return true; 18 else if (matrix[mid][0] < target) 19 lo = mid + 1; 20 else 21 hi = mid - 1; 22 } 23 int tmp = hi; //特别注意 24 //查找该行 25 lo = 0; 26 hi = col - 1; 27 while (lo <= hi) 28 { 29 int mid = (lo+hi) / 2; 30 if (matrix[tmp][mid] == target) 31 return true; 32 else if (matrix[tmp][mid] < target) 33 lo = mid + 1; 34 else 35 hi = mid - 1; 36 } 37 return false; 38 } 39 };
方法三:
class Solution { public: bool searchMatrix(vector<vector<int> > &matrix, int target) { int row = matrix.size(); int col = matrix[0].size(); if(row==0||col==0) return false; if(matrix[0][0]>target||target>matrix[row-1][col-1]) return false; //加与不加都行 int lo=0,hi=row*col-1; while(lo<=hi) { int mid=(lo+hi)/2; int i=mid/col; int j=mid%col; if(target==matrix[i][j]) return true; else if(target>matrix[i][j]) lo=mid+1; else hi=mid-1; } return false; } };