在很多算法面试题或者实际应用中,我们常常需要在一个矩阵中查找目标值。一个经典的问题是,在一个二维矩阵中查找一个值,该矩阵的特点是每行从左到右递增,且每列从上到下递增。面对这种情况,如何高效地查找目标值呢?
我们可以通过利用矩阵的递增特性来设计一个高效的查找算法。本文将详细讲解如何使用 右上角开始 的方法,设计一个时间复杂度为 O(m + n) 的查找算法。
给定一个二维矩阵,矩阵的每行元素是递增的,且每列元素也是递增的。我们需要在这个矩阵中查找一个给定的目标值。如果矩阵存在这个目标值,返回 true
,否则返回 false
。
矩阵的形式如下:
[
[1, 4, 7, 11],
[2, 5, 8, 12],
[3, 6, 9, 16],
[10, 13, 14, 17]
]
由于矩阵的每行和每列都是递增的,我们可以利用这个性质设计一个从右上角开始查找的算法。
matrix[0][n-1]
(第一行,最后一列)。true
。false
。这种方法的优势在于每次查找时,至少排除一整行或一整列,极大提高了查找效率。
下面是用 C 语言实现的查找算法:
#include
#include
// 查找矩阵中是否存在目标值
bool searchMatrix(int matrix[][4], int rows, int cols, int target) {
int row = 0; // 从矩阵的第一行开始
int col = cols - 1; // 从矩阵的最后一列开始
// 在矩阵中查找目标值
while (row < rows && col >= 0) {
if (matrix[row][col] == target) {
return true; // 找到目标值
} else if (matrix[row][col] > target) {
col--; // 目标值小,向左移动
} else {
row++; // 目标值大,向下移动
}
}
return false; // 如果遍历完矩阵没有找到目标值
}
int main() {
int matrix[4][4] = {
{1, 4, 7, 11},
{2, 5, 8, 12},
{3, 6, 9, 16},
{10, 13, 14, 17}
};
int target = 5; // 目标值
// 查找目标值并输出结果
if (searchMatrix(matrix, 4, 4, target)) {
printf("找到了目标值 %d\n", target);
} else {
printf("没有找到目标值 %d\n", target);
}
return 0;
}
searchMatrix
函数:
matrix
是二维矩阵,rows
是矩阵的行数,cols
是矩阵的列数,target
是要查找的目标值。matrix[0][cols-1]
开始,逐步根据当前值与目标值的大小关系决定是否向左或向下移动。main
函数:
5
。searchMatrix
函数进行查找,如果找到目标值则输出找到信息,否则输出未找到信息。时间复杂度:每一步我们都要么向左移动一列,要么向下移动一行。因此,最多需要遍历矩阵的 m + n
个元素,其中 m
是矩阵的行数,n
是矩阵的列数。因此,时间复杂度为 O(m + n)。
空间复杂度:我们只使用了常数空间存储变量 row
和 col
,因此空间复杂度为 O(1)。
假设我们有如下矩阵:
[
[1, 4, 7, 11],
[2, 5, 8, 12],
[3, 6, 9, 16],
[10, 13, 14, 17]
]
我们想要查找目标值 5
:
matrix[0][3]
,即 11
。由于 11
> 5
,我们向左移动。matrix[0][2]
,即 7
。由于 7
> 5
,我们继续向左移动。matrix[0][1]
,即 4
。由于 4
< 5
,我们向下移动。matrix[1][1]
,即 5
,找到了目标值,返回 true
。输出结果:
找到了目标值 5
通过使用 右上角开始 的查找策略,我们能够在一个递增矩阵中高效地查找目标值。该算法的时间复杂度为 O(m + n),比传统的暴力搜索(时间复杂度为 O(m * n))要高效得多。在实际应用中,尤其是对于大规模的矩阵,这种方法能够大大减少计算的时间。
希望这篇博客对你在算法和数据结构方面的学习有所帮助!