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]
]
总结: 两种方法的时间复杂度相同,O(logn)。
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.
在一个从左到右、从上到下方向元素保持递增的矩阵中,搜索是否存在特定元素。
因为元素保持递增,所以可以采用二分搜索来获得O(logn)的时间复杂度。
方法1:把整个矩阵看成一个递增的数列,运用二分搜索。
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
if(matrix.empty() || matrix[0].empty())
return false;
int Row = matrix.size(), Column = matrix[0].size();
if(matrix[0][0]>target || matrix[Row-1][Column-1]<target)
return false;
int left = 0, right = Row*Column-1;
int mid = (left+right)/2;
int current;
while(left<=right){
current = matrix[mid/Column][mid%Column];
if(current==target)
return true;
else if(current>target)
right = mid-1;
else
left = mid+1;
mid = (left+right)/2;
}
return false;
}
};
方法2:分两步,首先在行方向上运用二分搜索,找出元素可能存在的对应行;然后在列方向上运用二分搜索。
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
if(matrix.empty() || matrix[0].empty())
return false;
int Row = matrix.size(), Column = matrix[0].size();
if(matrix[0][0]>target || matrix[Row-1][Column-1]<target)
return false;
//find the right row
int left = 0, right = Row-1, mid = (left+right)/2;
while(left<right){
if(matrix[mid][0]>target)
right = mid-1;
else{
left = mid;
if(matrix[mid][Column-1]<target)
left = mid+1;
else
right = mid;
}
mid = (left+right)/2;
}
int row = mid;
//find the right column
left = 0;
right = Column-1;
while(left<=right){
mid = (left+right)/2;
if(matrix[row][mid]==target)
return true;
else if(matrix[row][mid]>target)
right = mid-1;
else
left = mid+1;
}
return false;
}
};
总结: 两种方法的时间复杂度相同,O(logn)。
方法1计算Row*Column可能会溢出,且需要很多的/和%运算。(参考https://oj.leetcode.com/discuss/10735/dont-treat-it-as-a-2d-matrix-just-treat-it-as-a-sorted-list)
方法2的代码则比较臃肿。