题目如下:
解题思路:
方法一:
二维数组有序,因此可以从右上角开始找,那样每次只需左移或者下移,即 row++ 或 col-- ,最大时间复杂度为O(m+n) 。
代码如下:
class Solution {
public:
//从右上角开始,要么往下走,要么往左走,最坏时间复杂度O(m+n)
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty())
return false;
int m = matrix.size();
int n = matrix[0].size();
int row = 0, col = n - 1; //从右上角开始检索
while(row < m && col >= 0){
if(matrix[row][col] < target && col == n-1) //先定位到行,后一个判断条件保证一旦行固定后只改变列
row++;
else if(matrix[row][col] == target)
return true;
else //再定位到列
col--;
}
return false;
}
};
方法二:
二维数组有序,因此可以直接采用二分法,将其从二维转化为虚拟的一维数组,最坏时间复杂度O(log(m*n))。
- 初始化左右元素,left = 0、right = m * n - 1,中位元素 middle = (left + right) / 2。middle对应原矩阵中的 row = midlle / n;col = middle % n ,由此可以拿到中间元素middle_element,将虚数组分为两部分;
- 比较 middle_element 与 target 以确定在哪一部分进行进一步查找。
代码如下:
class Solution {
public:
//=将二维数组作为虚拟一维数组进行处理,直接采用二分查找
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty())
return false;
//行和列
int m = matrix.size();
int n = matrix[0].size();
//二分查找
int left = 0;
int right = m * n - 1;
while(left <= right){
int middle = (left + right) / 2;
int middle_element = matrix[middle / n][middle % n];
if(middle_element == target)
return true;
else if(middle_element < target)
left = middle + 1;
else
right = middle - 1;
}
return false;
}
};