一、概述
很簡單的題,用最直觀的做法也可以做得出,那麼寫這個博客,是爲了記錄一種更好的做法——我這種直觀的做法沒法做到耗時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;
}
};
三、總結
這種不需要真正展開,僅需對下標進行修改就可以實現展開操作的做法十分值得學習。