0
点赞
收藏
分享

微信扫一扫

二分法:LeetCode74 - 搜索二维矩阵

泠之屋 2022-02-14 阅读 68

题目:

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 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

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

思路:

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

复杂度为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 条评论