一、概述
很简单的题,用最直观的做法也可以做得出,那么写这个博客,是为了记录一种更好的做法——我这种直观的做法没法做到耗时0ms,但是更好的做法可以。
二、分析
1、我的做法
首先搜索每行的第一个元素,确定要找的元素在哪一行,然后在该行搜索即可。
设矩阵有m行n列,则时间复杂度为O(m+n)。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& m, int t) {
if(m.size()==0||m[0].size()==0)
return false;
if(t<m[0][0]||t>m[m.size()-1][m[0].size()-1])
return false;
for(int i=0;i<m.size()-1;++i)
{
if(m[i][0]<=t&&m[i+1][0]>t)
for(int j=0;j<m[0].size();++j)
{
if(t==m[i][j])
return true;
if(t<m[i][j])
return false;
}
else
continue;
}
for(int j=0;j<m[0].size();++j)
{
if(t==m[m.size()-1][j])
return true;
if(t<m[m.size()-1][j])
return false;
}
return false;
}
};
2、较好的做法
由于矩阵有序,不妨把整个矩阵展开成一行,然后二分做。本做法这个展开操作很巧妙,可以学习一下。时间复杂度为O(log(mn))=O(logm+logn)。时间复杂度比我的要好。
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty()) return false;
int m = (int)matrix.size(), n = (int)matrix.front().size();
int start = 0, end = m*n - 1;
while(start <= end) {
int mid = start + (end - start)/2;
int e = matrix[mid/n][mid%n];
if(target == e) return true;
(target < e) ? end = mid - 1 : start = mid + 1;
}
return false;
}
};
三、总结
这种不需要真正展开,仅需对下标进行修改就可以实现展开操作的做法十分值得学习。