LeetCode 74 Search a 2D Matrix (Tag:Array Difficulty:Medium)

116 阅读2分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

前言

关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!

题目描述

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。

示例 1:

image.png
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true

示例 2:

image.png
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false

链接:leetcode-cn.com/problems/se…

题解

这道题目看上去是个二维的数组,每行数字递增,实际上可以将其看作一维的数组,只需要对下标做除,做余,即可将一维和二维对应起来。 而对于一维递增序列,找目标数,我们脑海里第一反应的做法就是二分法,因为二分法就是针对于有序序列而生。如果,有对二分法不熟悉的同学,可以看一下LeetCode 数组类型题目做前必看, 里面总结了二分法的常规套路。

所以这道题的核心在于将二维数组当作一维数组。我们假设一维数组的下标为 index, 二维数组每行有 n 个元素, 那么一维数组的下表换算到二维数组, 行号为 Math.floor(index / n), 列号为 index % n, 这样就把一维数组和二维数组对应起来了。 如果还不是很清楚,可以对照代码想想,代码如下。

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function(matrix, target) {
    const m = matrix.length
    const n = matrix[0].length
    let l = 0
    let r = m * n 
    while(l < r) {
        const mid = l + Math.floor((r - l) / 2)
        const row = Math.floor(mid / n) // 对应行号
        const col = mid % n //对应列号
        if (matrix[row][col] === target) return true 
        else if (matrix[row][col] > target) r = mid
        else l = mid + 1
    }
    return false
}