leetcode题解-74. 搜索二维矩阵

题目描述

原文链接:https://leetcode-cn.com/problems/search-a-2d-matrix/

编写一个高效的算法来判断 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

提示:

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

题目分析

题意大致就是在一个二维数组中查询是否有目标值,简单暴力的做法当然是双重for循环遍历每个值,在题目数据范围内是不会超时的,复杂度:O(n*m),略做优化,在外层循环中判断一下此数组范围是否包含target,包含再进入其中遍历,复杂度:O(n+m),理论上已经满足大部分情况了,但是仍然有更优秀的方案解决:对于这样的有序数组(二维数组)中的查找,我们首先就该想一下如何二分,因为二分查找的复杂度通常来说是O(log{_{n}})。那么这道题我们用二分的思路来思考有两种方法:

1.将二维数组整理为一维数组,然后二分查找

解析:这样做虽然在查找的时候很快捷,复杂度:O(log{_{n+m}}),但是整理的过程需要n+m的复杂度,有些本末倒置的味道,如果像本题目一样只查询一次,那么我们不应该选择这样的方法。

2.在二维数组上分别做二分查找,也就是先二分第一维数组,再二分第二维数组,听起来可能复杂,但实际上就是写了两次二分查找,复杂度:O(log{_{n}}+log{_{m}})

 

代码实现

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int n = matrix.length;
        int m = matrix[0].length;
//        System.out.println("n:"+n+" m:"+m);
        int i_left=0;       //一维左右指针
        int i_right=n-1;
        int j_left=0;       //二维左右指针
        int j_right=m-1;
        int i_mid=0;
        int j_mid=0;
        while(i_left<=i_right){
            i_mid = i_left+(i_right-i_left)/2;
//            System.out.println("i_mid:"+i_mid);
            if(matrix[i_mid][0]<=target&&matrix[i_mid][m-1]>=target){   //答案在此一维数组中
//                System.out.println("在一维数组:"+i_mid);
                j_left = 0;
                j_right = m-1;
                while(j_left<=j_right){
                    j_mid = j_left+(j_right-j_left)/2;
//                    System.out.println("j_mid:"+j_mid);
                    if(matrix[i_mid][j_mid]==target){
                        return true;
                    }else if(matrix[i_mid][j_mid]>=target){
                        j_right = j_mid-1;
                    }else {
                        j_left = j_mid+1;
                    }
                }
                return false;
            }else if(matrix[i_mid][0]>target){              //在左边的数组中
                i_right = i_mid-1;
            }else{
                i_left = i_mid+1;                           //在右边的数组中
            }
        }
        return false;
    }
}

写在最后

比较简单的二分题目,思路比较重要,要对有序数组保持敏感,优先二分。

欢迎交流,欢迎评论

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值