「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
前言
力扣第七十四题 搜索二维矩阵 如下所示:
编写一个高效的算法来判断 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
一、思路
既然要高校查找到有规律的矩阵中是否含有目标值,那么首先想到的肯定是二分法了。
因为矩阵每一行是从左至右递增的,而每一列也是递增的,且下一行的值一定会大于上一行的值,这是非常契合二分查找的。如下图所示:
我们为什么不把这个二维数组想象成一个递增的一维数组呢?那么问题就变成了在一个递增的一位数组中查找是否含有目标值?
既然想法有了,那么难题就变成了如何将二维数组的坐标映射成一维数组?其实这个也很简单,matrix[i][j] 这个位置就相当于一维数组中的 arr[j + i * colLen]。
例如
matrix[][]的大小为3 x 4转换成一维数组则为arr[]大小为12
那么matrix[2][2]相当于一维数组中的arr[10]
同理 arr[i] 相当于二维数组 matrix[i/colLen][i%colLen]
二、实现
实现代码
实现代码与思路中保持一致
public boolean searchMatrix(int[][] matrix, int target) {
int rowLen = matrix.length; // 行高
int colLen = matrix[0].length; // 列长
int left = 0;
int right = rowLen * colLen - 1;
while (left <= right) {
int mid = (right + left) / 2;
// mid/colLen 表示在第几行
int x = matrix[mid/colLen][mid%colLen];
if (x < target) {
left = mid + 1;
} else if (x > target) {
right = mid - 1;
} else {
// 如果等于,直接返回true
return true;
}
}
return false;
}
测试代码
public static void main(String[] args) {
int[][] matrix = {{1,3,5,7},{10,11,16,20},{23,30,34,60}};
new Number74().searchMatrix(matrix, 3);
}
结果
三、总结
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~