算法-二维数组查找系列

描述

在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例,现有矩阵 matrix 如下:

1
2
3
4
5
6
7
[
[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。

给定 target = 20,返回 false。

限制:

1
2
0<=n<=1000
0<=m<=1000

解决方案

二叉搜索

1. 二叉搜索

我们将矩阵逆时针旋转 45° ,并将其转化为图形式,发现其类似于 二叉搜索树 ,即对于每个元素,其左分支元素更小、右分支元素更大。因此,通过从 “根节点” 开始搜索,遇到比 target 大的元素就向左,反之向右,即可找到目标值
target 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int r = matrix.length;
int c = matrix[0].length;
for (int i = 0, j = c - 1; i < r && i >= 0 && j >= 0 && j < c; ) {
if (matrix[i][j] == target) {
return true;
} else if (matrix[i][j] < target) {
i++;
} else {
j--;
}
}
return false;
}
}

描述

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

每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。

示例图

解决方案

1. 二分搜索

映射到数据,进行二分查找。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int r = matrix.length;
int c = matrix[0].length;
int l = 0, h = r * c - 1;
while (l <= h) {
int mid = (h - l) / 2 + l;
int midValue = matrix[mid / c][mid % c];
if (midValue == target) {
return true;
} else if (midValue < target) {
l = mid + 1;
} else {
h = mid - 1;
}
}
return false;
}
}

算法-二维数组查找系列
http://example.com/2023/03/07/算法-二维数组查找系列/
作者
BiggerBrain
发布于
2023年3月7日
许可协议