目录
一、题目描述
二、解题思路
1、引言
2、思路推导过程
三、参考答案
一、题目描述
搜索二维矩阵
给你一个满足下述两条属性的 m x n
整数矩阵:
- 每行中的整数从左到右按非严格递增顺序排列。
- 每行的第一个整数大于前一行的最后一个整数。
给你一个整数 target
,如果 target
在矩阵中,返回 true
;否则,返回 false
。
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104
二、解题思路
1、引言
这道题目可以通过采用二分查找的思路来解决。我们首先观察到,矩阵的每一行都是有序的,而且每一行的第一个元素大于前一行的最后一个元素。这个特点使得我们可以通过不断地缩小搜索范围,逐渐接近目标值。但是正常情况下,我们二分查找的都是一维数组,这里却是个二维数组。
2、思路推导过程
那么,该怎么使用二分查找来查找一个二维数组呢?
相信,很多人会想到将这个二维数组转换成一维数组。然后再进行二分查找。但是这样是需要借助额外的空间的。也就是需要一个大小为m*n的一维数组来存储转换后的二维数组,其中,m为二维数组的行大小,n为二维数组的列大小。显然此时的空间复杂度为O(m*n)。这个时候不仅空间复杂度较高,代码也会较为复杂。
其实,我们仔细想一下。我们之所以想要把它转成一维数组不就是因为在二维数组中不好确定中间位置吗?比如,二维数组如下:
我们想要找到目标值28。我们可以在确定左右边界的时候,把它当做一个一维数组。那么在使用二分查找的话,初始搜索的左边界就为0,右边界就为m*n-1,也就是15。那么此时中间位置mid就是(0+15)/2=7。我们在确定中间位置的时候又需要将一维数组的位置转成二维数组的位置,这样我们才能从二维数组中获取到对应位置的值来和目标值进行比较。
一维数组的位置7对应二维数组的位置就是[1,3]。那么我们不难得出中间位置转成二维数组的位置后,所在行为mid/n,所在列就是mid%n。那么知道这个关系后,我们就可以在不借助额外空间的情况下,完成对该二维数组的查找。
三、参考答案
按照上述思路推导的过程的参考代码如下:
class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m = matrix.length, n = matrix[0].length;int l = 0, r = m * n - 1;while (l < r) {int mid = l + (r-l)/2; //等同于 (l + r)/2,写成 l + (r-l)/2是为了防止溢出if(matrix[mid/n][mid%n] >= target) r =mid;else l = mid +1;}return matrix[r/n][r%n] == target;}
}
总之, 搜索二维矩阵是一个经典的算法问题,通过使用二分查找的方法,我们可以快速地判断给定的目标值是否在矩阵中存在。该算法的时间复杂度为O(log(m*n)),其中m和n分别是矩阵的行数和列数,空间复杂度为O(1)。在面试和竞赛中,熟练掌握搜索二维矩阵的解决方法将对我们的算法能力有很大的提升。