LeetCode74.搜索二维数组[二分法] | 刷题打卡

76 阅读2分钟

题目描述

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

  • 每行中的整数从左到右按升序排列。

  • 每行的第一个整数大于前一行的最后一个整数。

示例 1:

img

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

示例 2:

img

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

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 100
  • -104 <= matrix[i][j], target <= 104

思路讲解

​ 因为这个二维数组是递增的,所以可以把他当成一个递增的一维数组来看待,数组的长度就是rows * cols .我们把它当成一个一维数组通过二分查找来找到target。这就涉及到一个问题,我么如何通过一维数组的下标来得到二维数组的x和y值,因为我们需要用二维数组中的数据和target来进行比较。具体方法就是x = index / cols,向下取整。y = index %cols。然后matrix【x】【y】与target比较,就是二分的那一套,结束的条件就是left <=right。

AC代码

/*
 * @lc app=leetcode.cn id=74 lang=javascript
 *
 * [74] 搜索二维矩阵
 */

// @lc code=start
/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var searchMatrix = function(matrix, target) {
    let rows = matrix.length;
    let cols = matrix[0].length;
    let left = 0;
    let right = cols*rows - 1;
    let mid = 0;
    while (left <= right) {
        mid = Math.floor((left + right) / 2);
        const [x,y] = getPosition(mid,cols);
        if (matrix[x][y] < target) {
            left = mid+1;
        } else if(matrix[x][y] > target){
            right = mid-1;
        }else {
            return true;
        }
    }
    return false;
    
    function getPosition(mid,cols) {
        let x = Math.floor(mid / cols);
        let y = mid % cols;
        return [x,y];
    }
};
// @lc code=end
let arr = [[1,3,5,7],[10,11,16,20],[23,30,34,60]]
console.log(searchMatrix(arr,3));

题目扩展

LeetCode240也是一道搜索二维数组的题目,这两道题目的区别就是240的二维数组是每行从左到右升序,每列从上到下升序。如下示例:

img

输入: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

这道题我们可以从右上角开始遍历,定义一个top和right。如果右上角的值大于target,那么说明target必定不在这一列中,可以将right--。如果右上角的值小于target,说明target一定不在这一行中,可以将top++。原理就是二维数组的右上角永远是这一行的最大值,这一列的最小值。

总结

二分法的时间复杂度是log(n)。需要注意如果把一个二维数组看作一维数组的话,通过一维数组的index如何得到对应元素的二维数组的x和y 的值。原理就是index / cols就是x,index %cols就是列。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情