这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
示例 2:
输入: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
}