力扣240题 搜索二维矩阵 II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。

  • 每列的元素从上到下升序排列。

示例 1:

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

示例 2:

输入: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 = 20
输出:false

解法思路:

1.直接查找

//给定一个二维数组
// const a = new Array(4).fill(0).map(() => new Array(5).fill(0));

//计算行的长度:4
//let length1 = arr.length;
//计算列的长度:5
//int length2 = arr[0].length;
var searchMatrix = 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;
};

复杂度分析

  • 时间复杂度:O(mn)。

  • 空间复杂度:O(1)。

2.二分查找

解法思路

看到有序,第一反应就是二分查找。最直接的做法,一行一行的进行二分查找即可。

此外,结合有序的性质,一些情况可以提前结束。

  • 某一行的第一个元素大于了 target ,当前行和后边的所有行都不用考虑了,直接返回 false。

  • 某一行的最后一个元素小于了 target ,当前行就不用考虑了,换下一行。

var searchMatrix = function(matrix, target) {
   for(const row of   matrix){
       // 取出二维数组的每行  为一个一维数组
        let res = erFenSearch(row, target);
        // 如果二分查找查到了target 就返回他的数组下标 下标一定是>=0的 此时就是查找到了
        if(res >= 0){
            return true;
        }
   }
    return false;
};
// 定义二分查找函数
const erFenSearch = (nums, target) => {
    let L = 0;
    let R = nums.length - 1;
    while(L<=R){
              let  mid = Math.floor((R -L)/2) + L;
        if(nums[mid] == target){
            return mid;
        }else if(nums[mid] < target){
            L = mid + 1;
        }else{
            R = mid - 1;
        }
    }
    return -1; 
}

复杂度分析

  • 时间复杂度:O(mlogn)。对一行使用二分查找的时间复杂度为 O(logn),最多需要进行 m 次二分查找。

  • 空间复杂度:O(1)。

3.不一样的二分查找(Z字形查找)

因为这个二维数组组成的表格,无论是从左往右,还是从上往下都是依次增大的数列,那么我们便可以从表格的右上角那个数开始判断,如果target小于这个值,那么那个数所在的那一列就可以去掉;如果target大于这个值,那么那个数所在的那一行就可以去掉,直至找到target或遍历完整个二维数组。

推荐后两种!

var searchMatrix = function(matrix, target) {
// 首先定义出右上角数字的行列下标
    for(let i = 0, j = matrix[i].length - 1; i < matrix.length && j >= 0; i++){
// 如果这个数就是target 直接return true
        if(matrix[i][j] == target){
            return true;
        }
// 如果target大于右上角那个数 说明这一行就可以不用看了 直接continue下一次循环 每次循环只操作行的参数i
        else if(matrix[i][j] < target){
            continue;
        }
// 如果target小于右上角那个数 说明这一列就不用看了 直接j-- 到当前列的前一列 但是此时行数不能改变 还是当前这行 所i=i-1
        else{
            j--;
            i = i - 1;
        }
    }
    return false;
};
class Solution {
   public boolean searchMatrix(int[][] matrix, int target) {
    if (matrix.length == 0 || matrix[0].length == 0) {
        return false;
    }
    int row = 0;
    int col = matrix[0].length - 1;
    while (row < matrix.length && col >= 0) {
        if (target > matrix[row][col]) {
            row++;
        } else if (target < matrix[row][col]) {
            col--;
        } else {
            return true;
        }
    }
    return false;
}
}
var searchMatrix = function(matrix, target) {
     if (matrix.length == 0 || matrix[0].length == 0) {
        return false;
    }
    let H = 0;
    let L = matrix[0].length - 1;
    while(H < matrix.length && L >= 0){
        if(matrix[H][L] == target){
        return true;
        }else if(matrix[H][L] < target){
            H++;
        }else{
            L--;
        }
    }
    
    return false;
    
};

复杂度分析

  • 时间复杂度就是每个节点最多遍历一遍了,O(m + n)。

  • 空间复杂度:O(1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值