「前端刷题」240.搜索二维矩阵 II(MEDIUM)

78 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

题目(Search a 2D Matrix II)

链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii
解决数:1547
通过率:52.2%
标签:数组 二分查找 分治 矩阵 
相关公司:amazon microsoft bytedance 

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

示例 2:

输入: 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 <= n, m <= 300
  • -109 <= matrix[i][j] <= 109
  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列
  • -109 <= target <= 109

思路

  • 左下角起,向上单调递减,向右单调递增
  • 左下角起,当前数比目标值向右移动一格。向上移动一格
  • 最终找到目标值找不到越界

代码

var searchMatrix = function(matrix, target, i = matrix.length - 1, j = 0) {
    while (i > -1 && j < matrix[0].length) 
        if (matrix[i][j] === target) return true
        else matrix[i][j] > target ? i-- : j++
    return false
};

思路2,双指针 · 单调区间 · 右上角

  • 右上角起,向左单调递减,向下单调递增
  • 右上角起,当前数比目标值向下移动一格。向左移动一格
  • 最终找到目标值找不到越界

代码

var searchMatrix = function(matrix, target) {
    if (matrix.length === 0) return false
    var i = 0, j = matrix[0].length - 1
    while (i < matrix.length && j > -1) 
        if (matrix[i][j] === target) return true
        else matrix[i][j] > target ? j-- : i++
    return false
};

思路3,双指针 · 对角线 + 列 + 行

  • 对角线双指针:对角线[0,0][m, m][n, n],找目标值
  • 从对角线最接近目标值的点[l, l]向右,遍历[l, n]
    • 行双指针:每列[0, l]行,找目标值
  • 从对角线最接近目标值的点[l, l]向右,遍历[l, m]
    • 列双指针:每行[0, n - 1]列,找目标值

代码

var searchMatrix = function(matrix, target) {
    if (matrix.length === 0) return false
    var m = matrix.length, n = matrix[0].length, l = 0, s = (l, r, f) => {
        while (l <= r) {
            var m = l + (r - l >>> 1), t = f(m)
            if (t === target) return -2
            else if (t > target) r = m - 1
            else l = m + 1
        }
        return l - 1
    }
    if ((l = s(0, Math.min(m, n) - 1, (m) => matrix[m][m])) === -2) return true
    else if (l === -1) return false
    for (var i = l; ++i < n;) if (s(0, l, (m) => matrix[m][i]) === -2) return true
    for (var i = l; ++i < m;) if (s(0, n - 1, (m) => matrix[i][m]) === -2) return true
    return false
};