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

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


LeetCode 74 - 搜索二维矩阵 (二分法)_第1张图片

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

LeetCode 74 - 搜索二维矩阵 (二分法)_第2张图片

输入: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>& matrix, int target) {
        int m=matrix.size(), n=matrix[0].size(), line=-1;
        if(m==0 || n==0) return false;
        if(targetmatrix[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 "<=matrix[mid][0] && target=matrix[mid+1][0]) low=mid+1;
            else if(targettarget) high=mid-1;
        }
        return false;
    }
};

二叉树

class Solution {
public:
    bool searchMatrix(vector>& 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(currenttarget) start_n--;
            if(start_m==m || start_n<0) return false;
        }
        return false;
    }
};

收获:

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

你可能感兴趣的:(矩阵,线性代数,算法,二分法)