[LeetCode240. 搜索二维矩阵 II]|刷题打卡

583 阅读2分钟

题目描述

编写一个高效的算法来搜索 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

示例 2:

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 = 20
输出:false

思路分析

  1. 我的想法是: 由于每行每列已经排好序了,那就一行一行的进行二分法,时间复杂度我也不会计算,总之小于 O(n^2). 当然,这个方法时间复杂度还是很高的,看了题解才知道有一个更简单,并且时间复杂度更低的算法
  2. 这个算法完全利用了 二维矩阵的特性,从二维矩阵的左下角开始向上和向右遍历,该点的上方都比该值小,该点的右方都比该值大,所以可以进行剪切式的遍历,将数组一行一行的减小。比如:目标值为8,最左下角的值为18,那么因为 18 > 8,目标值比该值小,所以向上移动一行。经过这样,如果超出数组长度,则没有目标值,不然可以找到。

AC代码

每行二分

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function (matrix, target) {
  let y = 0
  while (y < matrix.length) {
    let min = 0, max = matrix[0].length - 1
    while (min <= max) {
      let mid = parseInt((min + max) / 2)
      if (matrix[y][mid] === target) {
        return true
      }
      else if (matrix[y][mid] > target) {
        max = mid - 1
      }
      else {
        min = mid + 1
      }
    }
    y++
  }
  return false
};

裁剪法

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function (matrix, target) {
  let n = matrix.length - 1
  let m = 0
  while(m<matrix[0].length&&n >=0) {
    if(matrix[n][m]>target){
      n--
    }
    else if(matrix[n][m]<target) {
      m++
    }
    else {
      return true
    }
  }
  return false
};

总结

从这一题可以看出,算法在很多地方都跟数学扯上了关系