方法一:
二维数组有序,因此可以从右上角开始找,那样每次只需左移或者下移,即 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; } };