LeetCode 74 - 搜索二维矩阵 (二分法)

74. 搜索二维矩阵 - 力扣(LeetCode) (leetcode-cn.com)icon-default.png?t=M1L8https://leetcode-cn.com/problems/search-a-2d-matrix/

题目:

Write an efficient algorithm that searches for a value target in an m x n integer matrix matrix. This matrix has the following properties:

Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row

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

每行中的整数从左到右按升序排列
每行的第一个整数大于前一行的最后一个整数


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

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

思路:

对于有序的矩阵容易想到二分法。注意二分法的细节实现。为了确保有解,一开始先判断两个边界条件,确定有解才进行二分搜索。对于行的二分,由于是寻找区间,也要先对边界条件进行处理。

复杂度为O(log m*n)

另外一个思路是利用矩阵的有序性构造二叉树。例如对于矩阵的每一个数,将其视为二叉树的一个节点,向左延申为左子树,向下为右子树。根据二叉树搜索的规则进行搜索。这个想法没那么直接,但是代码非常简洁高效

复杂度为O(m+n)


题解:

二分法

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m=matrix.size(), n=matrix[0].size(), line=-1;
        if(m==0 || n==0) return false;
        if(target<matrix[0][0] || target>matrix[m-1][n-1]) return false;
        int low=0, high=m-2, mid=-1;
        /* find out which line */
        if(target>=matrix[m-1][0]) line=m-1;
        else while(low<=high){
            mid=(low-high)/2+high;
            //cout<<"the mid is "<<mid<<endl;
            if(target>=matrix[mid][0] && target<matrix[mid+1][0]) {
                line=mid; break;
            }
            else if(target>=matrix[mid+1][0]) low=mid+1;
            else if(target<matrix[mid][0]) high=mid-1;
        }

        /* find out which column */
        low=0, high=n-1;
        while(low<=high){
            mid=(low-high)/2+high;
           // cout<<"the mid is "<<mid<<endl;
            if(matrix[line][mid]==target) return true;
            else if(matrix[line][mid]<target) low=mid+1;
            else if(matrix[line][mid]>target) high=mid-1;
        }
        return false;
    }
};

二叉树

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m=matrix.size(), n=matrix[0].size(), line=-1;
        int start_m=0, start_n=n-1;
        while(1){
            int current=matrix[start_m][start_n];
            if(current==target) return true;
            else if(current<target) start_m++;
            else if(current>target) start_n--;
            if(start_m==m || start_n<0) return false;
        }
        return false;
    }
};

收获:

牢记二分法的模板,写代码的效率增加了。同时二叉树的方法拓展了我的思路。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值