力扣 74. 搜索二维矩阵

题目说明

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。

  • 每行的第一个整数大于前一行的最后一个整数。

  • 提示:

    • m == matrix.length
    • n == matrix[i].length
    • 1 <= m, n <= 100
    • -104 <= matrix[i][j], target <= 104

示例

例1

image.png

1
2
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true

例2

image-20210330101932328

1
2
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false

笔者理解

此题是一道二分查找算法问题,在力扣题库中被定义为中等题。

解法

当笔者阅读完此题后,发现此题是非常经典的二分查找,只是将一维变成了二维,注意对应一二维位置的转化即可,让我们来看看具体如何实现的吧。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public boolean searchMatrix(int[][] matrix, int target) {
int row = matrix.length;
int column = matrix[0].length;

// 唯一元素时
if (row * column == 1) {
return target == matrix[0][0];
}

// 目标不在矩阵中
if (target > matrix[row - 1][column - 1] || target < matrix[0][0]) {
return false;
}

// 左右边界
int left = 0;
int right = row * column - 1;

// 中间指针及其对应的值
int mid;
int num;

while (left <= right) {
mid = left + (right - left) / 2;
num = matrix[mid / column][mid % column];

// 找到了
if (target == num) {
return true;
}
// 目标大于中间元素,左边界右移
else if (target > num) {
left = mid + 1;
}
// 目标小于中间元素,右边界左移
else {
right = mid - 1;
}
}

return false;
}

时间和空间效率都还行,可见此解法还比较适合此题;

image.png

总结

本题是今天的每日一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。