[路飞]_240.搜索二维矩阵 II

166 阅读2分钟

「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战

240. 搜索二维矩阵 II

题目

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

示例1

image.png

输入: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

题解

暴力枚举

搜索二维数组目标值,直接暴力枚举二维数组所有元素,判断 targettarget 是否出现即可。

时间复杂度:O(mn)O(mn)

显然,这不是一个高效的算法。并且没有利用每行的元素从左到右升序排列这个特性

二分法

题目中给出

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。 这两个特点。通过以往的经验可知,有序算法寻找目标值,二分法可以将时间复杂度降低到 log(n)log(n) 级别

因此在枚举过程中,对枚举到的每一行使用一次二分查找,判断 targettarget 是否出现在该行中,从而判断  targettarget  是否出现。

时间复杂度:O(mlog(n))O(m*log(n))

Z字形查找

我以为二分法已经是最优解了,去看了官方题解。真佩服算法大神们的思路;将题目中给出的元素有序排列运用到了极致。

Z字形查找

从二维数组的右上角[0,n1][0,n-1] 位置开始搜索,假如此时坐标为x,yx,y

  • matrix[x][y]===targetmatrix[x][y] === target ,二维数组存在 targettarget
  • matrix[x][y]>targetmatrix[x][y] > target,因为题目中说每一列的元素都是升序排列的,所以在此处 yy 列的元素此是一定大于 targettarget 的,所以此时应该向 y1y-1 方向搜索
  • matrix[x][y]<targetmatrix[x][y] < target,因为题目中说每一行的元素都是升序排列的,所以在此处 xx 行的元素此是一定小于 targettarget 的,所以此时应该向 x+1x+1 方向搜索
  • 如果越界,表示二维数组不存在 targettarget

根据上述思路编辑代码如下:

代码

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;
};