一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情。
每日一题——搜索二维矩阵
题目信息描述
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 输出:true
示例 2:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 输出:false
提示:
- m == matrix.length
- n == matrix[i].length
- 1 <= m, n <= 100
- -104 <= matrix[i][j], target <= 104
思路
解法一:
可以根据矩阵的排列顺序得出规律,即:每一行的最后一个数一定大于每一行的第一个数,且小于第二行的最后一个数字,于是我们可以从第一行的右上角进行搜寻,如果这个数大于target,那么列-1,否则行+1,这样就可以搜寻出答案。
注意:这样的时间复杂度为O(n + m)
解法二:
这个做法是在解法一的基础上进行改进,先根据矩阵的特性搜寻出target所在的行,然后使用二分对那一行的所有数字进行搜寻
**注意:**时间复杂度为O(long2m)
解法三:
在解法二的基础上进一步改进,使用两次二分搜寻,第一次找出目标值所在的行,第二次在那一行使用二分查找出目标值
**注意:**这样的做法的时间复杂度为O(long2m)
代码
解法一:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n = matrix.size(), m = matrix[0].size();
int i = 0, j = m - 1;
while(true)
{
if(i >= n || j < 0) return false;
if(matrix[i][j] == target) return true;
if(matrix[i][j] < target) i ++;
else if(matrix[i][j] > target) j -- ;
}
return false;
}
};
解法二:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n = matrix.size(), m = matrix[0].size();
int i = 0, j = m - 1;
while(i < n && matrix[i][j] < target) i ++;
if(i >= n) return false;
if(matrix[i][j] == target) return true;
// 对本行进行二分搜寻
int left = 0, right = m - 1;
while(left < right)
{
int mid = (left + right) / 2;
if(matrix[i][mid] >= target) right = mid;
else left = mid + 1;
}
if(matrix[i][left] != target) return false;
return true;
}
};
解法三:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int n = matrix.size(), m = matrix[0].size();
// 对本行进行二分搜寻
int left = 0, right = n - 1;
while(left < right)
{
int mid = (left + right) / 2;
if(matrix[left][0] <= target && matrix[mid][m - 1] >= target) right = mid;
else left = mid + 1;
}
int row = left;
// 对本行进行二分搜寻
left = 0, right = m - 1;
while(left < right)
{
int mid = (left + right) / 2;
if(matrix[row][mid] >= target) right = mid;
else left = mid + 1;
}
if(matrix[row][left] != target) return false;
return true;
}
};