携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
搜索二维矩阵
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性: 每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。
来源:力扣(LeetCode) 链接:leetcode.cn/problems/se…
暴力破解
- 二重循环遍历二维数组,遍历完就知道有没有这个目标值,但是时间复杂度比较高O(mn)
代码
var searchMatrix = function(matrix, target) {
for(let i = 0; i < matrix.length; i++) {
for(let j = 0; j < matrix[0].length; j++) {
if(matrix[i][j] === target) return true
}
}
return false
};
二分查找
- 每一行是有序的,分别对m行进行二分,时间复杂度为O(mlogn)
代码
var searchMatrix = function(matrix, target) {
for(let i = 0; i < matrix.length; i++) {
let start = 0, end = matrix[0].length - 1
while(start <= end) {
let mid = Math.floor((start + end) / 2)
if(matrix[i][mid] === target) return true
if(matrix[i][mid] > target) end = mid - 1
else start = mid + 1
}
}
return false
}
二分查找的优化
- 除了每一行有序,每一行的第一个数字大于上一行的最后一个,可以把二维数组打平,把矩阵看成是一个一维数组,每一行首尾相连之后就是一个整体有序的数组,对整体用二叉查找,时间复杂度为O(logmn)
代码
var searchMatrix = function(matrix, target) {
let start = 0, end = (matrix.length * matrix[0].length) - 1
while(start <= end) {
let mid = Math.floor((start + end) / 2)
let midNum =
matrix[Math.floor(mid / matrix[0].length)][mid % matrix[0].length]
if(midNum === target) return true
else if(midNum < target) start = mid + 1
else end = mid - 1
}
return false
}
总结
- 本题的难度是中等,推荐的解题方法是二分法
- 这道题也是对二分法的一个扩展:就像上一篇说的,二分法的核心就是有序,寻找目标值,矩阵的每行是有序的,每行首尾相连之后,也是有序的,因此可以对矩阵整体进行二分,之后的解题难点可能是最中点位置的计算
- 今天也是有收获的一天