Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
一、题目:
leetcode 搜索二维矩阵
编写一个高效的算法来判断 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
二、题解:
1.解读 二维数组中查找元素,然后二维数组也是有一定规则顺序的(每行元素是升序,每行第一个数字大于上一行最后一个数字),所以很明显的可以使用二分查找了。
方法一
因为每行的元素都是从左到右升序的并且第一个整数大于前一行的最后一个整数,所以每一列的元素也必然是从上到下升序的。因此我们可以对第一列的元素进行二分查询来确定目标数target可能在哪一行,
找到目标所在行之后再对该行二分查找是否存在目标数target。
方法二 基于整个二维数组都是从左到右从上到下的顺序升序的,所以可以将二维数组的第一行尾部与第二行头部这样连接,最后就会得到一个升序的一维数组,那么可以直接对这个数组进行二分查找,判断是否存在 目标值。
三、代码:
方法一 Java代码
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int left = -1;
int right = matrix.length - 1;
while (left < right) {
int mid = (right - left + 1) / 2 + left;
if (matrix[mid][0] <= target) {
left = mid;
} else {
right = mid - 1;
}
}
if (left <0) {
return false;
}
int row = left;
left = 0;
right = matrix[row].length - 1;
while (left <= right) {
int mid = (right - left) / 2 + left;
if (matrix[row][mid] == target) {
return true;
}
if (matrix[row][mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return false;
}
}
时间复杂度:O(log n),两次二分查找。
空间复杂度:O(1),参数个空间变量。
方法二 Java代码
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int left = 0;
int right = m * n - 1;
int t;
while (left <= right) {
int mid = (right - left) / 2 + left;
if (matrix[mid / n][mid % n] == target) {
return true;
}
if (matrix[mid / n][mid % n] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}
}
时间复杂度:O(log n),一次二分查找。
空间复杂度:O(1),参数个空间变量。
四、总结
方法二是基于二维数组中的一维数组长度一致的情况,否则就用方法一处理。