搜索二维矩阵
一、题目背景
在LeetCode上,有一道经典的二维矩阵搜索问题------"搜索二维矩阵 II"。题目要求在一个具有特定性质的二维矩阵中查找目标值。矩阵的每一行从左到右升序排列,每一列从上到下升序排列。我们需要设计一个高效的算法来判断目标值是否存在于矩阵中。
二、题目描述
给定一个二维矩阵matrix
和一个目标值target
,矩阵的行数为m
,列数为n
。矩阵满足以下性质:
- 每一行的元素从左到右升序排列。
- 每一列的元素从上到下升序排列。
我们需要判断目标值target
是否存在于矩阵中。
示例 1:
输入:
plaintext
matrix = [
[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
示例 2:
输入:
plaintext
matrix = [
[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 = 20
输出:false
约束条件:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
-10^9 <= matrix[i][j] <= 10^9
- 每一行的所有元素从左到右升序排列
- 每一列的所有元素从上到下升序排列
-10^9 <= target <= 10^9
三、解题思路分析
1. 错误思路回顾
在解题过程中,我们可能会尝试一些直观的思路,但这些方法往往效率低下或存在逻辑错误。例如,从矩阵的左上角开始逐行逐列搜索,或者在矩阵中随机选择一个起点进行搜索。这些方法的时间复杂度较高,无法满足题目对效率的要求。
2. Z字形查找算法
经过分析,我们发现一种高效的搜索方法------Z字形查找。这种方法利用了矩阵的有序性,从矩阵的右上角(或左下角)开始搜索,通过逐步调整搜索范围,快速定位目标值。
算法步骤:
- 初始化 :从矩阵的右上角开始搜索,设当前坐标为
(x, y)
,其中x = 0
,y = n - 1
。 - 搜索过程 :
- 如果
matrix[x][y] == target
,说明找到了目标值,返回true
。 - 如果
matrix[x][y] > target
,由于每一列是升序排列的,当前列的所有元素都大于目标值,因此将y
减1,即向左移动。 - 如果
matrix[x][y] < target
,由于每一行是升序排列的,当前行的所有元素都小于目标值,因此将x
加1,即向下移动。
- 如果
- 边界条件 :如果搜索过程中超出矩阵的边界(
x >= m
或y < 0
),说明目标值不存在,返回false
。
3. 算法优势
Z字形查找算法充分利用了矩阵的有序性,避免了不必要的搜索。其时间复杂度为O(m + n) ,其中m
是矩阵的行数,n
是矩阵的列数。相比暴力搜索(时间复杂度为O(m * n)),这种方法效率显著提高。
四、代码实现
以下是基于Z字形查找算法的C语言实现:
c
bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {
int m = matrixSize; // 矩阵的行数
int n = *matrixColSize; // 矩阵的列数
int x = 0, y = n - 1; // 从右上角开始搜索
while (x < m && y >= 0) { // 确保搜索范围在矩阵内
if (matrix[x][y] == target) { // 找到目标值
return true;
} else if (matrix[x][y] > target) { // 当前值大于目标值,向左移动
y--;
} else { // 当前值小于目标值,向下移动
x++;
}
}
return false; // 超出矩阵边界,目标值不存在
}
代码说明:
- 初始化 :
x
为0,y
为矩阵的列数减1,即从右上角开始。 - 循环条件 :
x < m
且y >= 0
,确保搜索范围在矩阵内。 - 搜索逻辑 :
- 如果当前值等于目标值,直接返回
true
。 - 如果当前值大于目标值,向左移动(
y--
)。 - 如果当前值小于目标值,向下移动(
x++
)。
- 如果当前值等于目标值,直接返回
- 返回结果 :如果超出矩阵边界仍未找到目标值,返回
false
。
五、测试用例
测试用例 1:
plaintext
matrix = [
[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
测试用例 2:
plaintext
matrix = [
[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 = 20
输出 :false
测试用例 3:
plaintext
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
target = 7
输出 :true
六、总结
通过Z字形查找算法,我们能够高效地解决"搜索二维矩阵 II"问题。这种方法充分利用了矩阵的有序性,避免了暴力搜索的低效性。在实际应用中,我们还可以根据矩阵的性质选择其他优化策略,例如从左下角开始搜索,逻辑与从右上角类似。
这题本质上就是从右上角往右下角遍历,还是比较容易的。