leetcode—— 二维数组中的查找

163 阅读1分钟

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

前言

力扣练习第二天,拒绝思路老化。今天要练习的是二维数组中的查找

看看题目信息: 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
 
/**
*  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,return true。
*  target = 20,return false。
*/

解法一

这道题,第一反应肯定是暴力法啦,对数组进行循环,对每个元素也进行循环,找到则return true,否则return false

var findNumberIn2DArray = function(matrix, target) {
    for(let i = 0; i < matrix.length; i++) {
        for(let j = 0; j < matrix[i].length; j++) {
            if(matrix[i][j] === target) {
                return true;
            }
        }
    }
    
    return false
};

两次循环,时间复杂度m*n,也就是O(n^2),太高了。能不能优化呢?答案是可以

解法二

仔细观察数组,我们会发现,二维数组的同一行元素,后一列都比前面的数值大,二维数组的同一列元素,后一行都比前面的数值大。啊,抱歉,题目信息也给出了,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序的信息。那么我们就不难得出这样的思路:

  • 以二维数组左下角为原点,建立直角坐标轴。
  • 若当前数字大于target,查找往上移一位。
  • 若当前数字小于target,查找往右移一位。

图解呢推荐看这个二维数组中的查找

思路有了,代码很快也就出来了:

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

当然还有其他思路,二分查找,降维啊,个人认为都不如上述通俗易懂,所以在这也就不实现了。