「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」
题目
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
示例1
输入: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
题解
暴力枚举
搜索二维数组目标值,直接暴力枚举二维数组所有元素,判断 是否出现即可。
时间复杂度:
显然,这不是一个高效的算法。并且没有利用每行的元素从左到右升序排列这个特性
二分法
题目中给出
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。 这两个特点。通过以往的经验可知,有序算法寻找目标值,二分法可以将时间复杂度降低到 级别
因此在枚举过程中,对枚举到的每一行使用一次二分查找,判断 是否出现在该行中,从而判断 是否出现。
时间复杂度:
Z字形查找
我以为二分法已经是最优解了,去看了官方题解。真佩服算法大神们的思路;将题目中给出的元素有序排列运用到了极致。
Z字形查找
从二维数组的右上角 位置开始搜索,假如此时坐标为
- ,二维数组存在
- ,因为题目中说
每一列的元素都是升序排列的,所以在此处 列的元素此是一定大于 的,所以此时应该向 方向搜索 - ,因为题目中说
每一行的元素都是升序排列的,所以在此处 行的元素此是一定小于 的,所以此时应该向 方向搜索 - 如果越界,表示二维数组不存在
根据上述思路编辑代码如下:
代码
var searchMatrix = function(matrix, target) {
let m = matrix.length;
if (m == 0) return false;
let n = matrix[0].length;
let row = 0;
let col = n - 1;
while (row < m && col >= 0) {
if (matrix[row][col] == target) return true;
if (matrix[row][col] > target) {
col--;
} else {
row++;
}
}
return false;
};