[Leetcode] Search a 2D Matrix

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<vector<int> > &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<vector<int> > &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<vector<int> > &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<vector<int> > &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<vector<int> > &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 };

 

posted @ 2014-04-02 22:55  Eason Liu  阅读(193)  评论(0编辑  收藏  举报