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
.
从右上角向左下角搜索,初始row = 0, col = n - 1; 如果当前值等于目标值,返回真,如果以目标值大,则舍弃当前列,否则舍弃当前行。
1 class Solution { 2 public: 3 bool searchMatrix(vector> &matrix, int target) { 4 int row = 0, col = matrix[0].size() - 1; 5 while (row < matrix.size() && col >=0) { 6 if (matrix[row][col] == target) { 7 return true; 8 } else if (matrix[row][col] > target) { 9 --col;10 } else {11 ++row;12 }13 }14 return false;15 }16 };
第二遍做的时候发现其实这个矩阵不完全是杨氏矩阵,可以使用二分搜索,下面是代码。
1 class Solution { 2 public: 3 bool searchMatrix(vector> &matrix, int target) { 4 int m = matrix.size(); 5 int n = matrix[0].size(); 6 int L = 0, R = n * m - 1, M; 7 int col, row; 8 while (L <= R) { 9 M = L + ((R - L) >> 1);10 row = M / n;11 col = M % n;12 if (matrix[row][col] > target) R = M - 1;13 else if (matrix[row][col] < target) L = M + 1;14 else return true;15 }16 return false;17 }18 };
上面是对所有元素二分,复杂度是log(n*m),还可以更优化一点,对于普通的杨氏矩阵也适用,复杂度为log(n)+log(m).
1 class Solution { 2 public: 3 bool searchMatrix(vector> &matrix, int target) { 4 int row = lowerBound(matrix, target); 5 if (row == -1) return false; 6 return binSearch(matrix, target, row); 7 } 8 9 int lowerBound(vector > &matrix, int target) {10 int L = 0, R = matrix.size() - 1, M;11 while (L <= R) {12 M = L + ((R - L) >> 1);13 if (matrix[M][0] <= target) L = M + 1;14 else R = M - 1;15 }16 return R;17 }18 19 bool binSearch(vector > &matrix, int target, int row) {20 int L = 0, R = matrix[row].size() - 1, M;21 while (L <= R) {22 M = L + ((R - L) >> 1);23 if (matrix[row][M] < target) L = M + 1;24 else if (matrix[row][M] > target) R = M - 1;25 else return true;26 }27 return false;28 }29 };