12.25 2014
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
.
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int i=0;
int n=matrix.size();
int m=matrix[0].size();
int row=0;
while(i<n){
if(target==matrix[i][0])
return true;
else if(target>matrix[i][0]){
row=i;
i++;
}
else if(target<matrix[i][0] && i!=0){
if(target>matrix[i-1][m-1])
return false;
else if(target==matrix[i-1][m-1])
return true;
else{
row=i-1;
break;
}
}
else if(target<matrix[i][0] && i==0)
return false;
}
int begin=0;
int end=m-1;
while(begin<=end){
int mid=(begin+end)/2;
if(matrix[row][mid]==target)
return true;
else if(matrix[row][mid]<target)
begin=mid+1;
else
end=mid-1;
}
return false;
}
};
第一步是先确定row的位置。细节实现一下即可,根据不同的情况分类讨论一下,唯一要注意的是当i是零时,要特别处理,此时若target小于第一排的第一个数,那么肯定无法在该matrix里面找到。在确定了行的情况下,用二分法查找。该步实现时要注意,while循环条件有所不同,是begin<=end,因为可能begin和end会重合且可能该位置就是target的位置。后来转念一下为何不两步都使用二分法呢?
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int i=0;
int n=matrix.size();
int m=matrix[0].size();
int begin=0;
int end=n-1;
while(begin<=end){
int mid=(begin+end)/2;
if(matrix[mid][0]==target)
return true;
else if(matrix[mid][0]<target)
begin=mid+1;
else
end=mid-1;
}
int row=end<0?begin:end;
begin=0;
end=m-1;
while(begin<=end){
int mid=(begin+end)/2;
if(matrix[row][mid]==target)
return true;
else if(matrix[row][mid]<target)
begin=mid+1;
else
end=mid-1;
}
return false;
}
};
不同在于第一步。while条件仍为begin<=end。需要注意的地方时row的取值。一般条件下row的取值为end,但是考虑到第一排的关系,所以还应该判断end是否为-1;
第一个代码跑了86ms 第二个跑了56ms 时间性能提升