小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
示例
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false
提示
m == matrix.lengthn == matrix[i].length1 <= n, m <= 300-10<= matrix[i][j] <= 10- 每行的所有元素从左到右升序排列
- 每列的所有元素从上到下升序排列
-10<= target <= 10
解题思路
暴力法
对于矩阵查找目标值,最简单的实现就是两层遍历即可找到所需的结果。
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int top = 0, bottom = matrix.length, left = 0, right = matrix[0].length;
for(int i = top; i < bottom; ++i){
for(int j = left; j < right; ++j){
if(matrix[i][j] == target){
return true;
}
}
}
return false;
}
}
复杂度分析
- 时间复杂度:
- 空间复杂度:
二分法
然而提示中还给我们提供多了两条信息:
- 每行的所有元素从左到右升序排列
- 每列的所有元素从上到下升序排列
对于有序的排列,我们就可以选择 二分法 来缩短排查的时间。
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int top = 0, bottom = matrix.length;
for(int i = top; i < bottom; ++i){
int left = 0, right = matrix[0].length;
while(left < right){
int mid = left + (right - left) / 2;
if(matrix[i][mid] == target){
return true;
}else if(matrix[i][mid] < target){
left = mid + 1;
}else{
right = mid;
}
}
}
return false;
}
}
复杂度分析
- 时间复杂度:
- 空间复杂度:
二分优化
对于上面的二分查找来说,不管是按行还是按列来排查,都需要一排排的逐行/列排查,对于有序的矩阵来说,当前位置坐标点(x, y)的值一定是比(x - 1, y), (x, y - 1)的值大,那么我们可以利用该特性来缩小排查范围,呈扇形范围扫描区间元素是否符合。
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1;
while(top <= bottom && left <= right){
if(matrix[bottom][left] == target){
return true;
}else if(matrix[bottom][left] > target){
--bottom;
}else{
++left;
}
}
return false;
}
}
复杂度分析
- 时间复杂度:
- 空间复杂度:
最后
文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!
如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!