LintCode-28. 搜索二维矩阵

题目描述

写出一个高效的算法来搜索 m × n矩阵中的值。
这个矩阵具有以下特性:
每行中的整数从左到右是排序的。
每行的第一个数大于上一行的最后一个整数。
样例
考虑下列矩阵:
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
给出 target = 3,返回 true
挑战
O(log(n) + log(m)) 时间复杂度

分析

因为是有序的,所以直接看每个小列表的最后一个是不是小于这个数就知道在不在这个小列表里了。

代码

class Solution {
public:
    /*
     * @param matrix: matrix, a list of lists of integers
     * @param target: An integer
     * @return: a boolean, indicate whether matrix contains target
     */
    bool searchMatrix(vector<vector<int>> &matrix, int target) {
        // write your code here
        for(vector<int> i : matrix) {
            if(i.back() >= target) {
                for(int j : i) {
                    if(j == target) return true;
                }
            }
        }
        return false;
    }
};

优化

根据挑战的提示:时间复杂度为O(log(n) + log(m)),即O(logMN)。再根据题目中所说的行列均有序可以发现使用两次二分法查找并且没有重复元素。不过需要注意外层二分法条件与正常不同,代码如下:

class Solution {
public:
    /*
     * @param matrix: matrix, a list of lists of integers
     * @param target: An integer
     * @return: a boolean, indicate whether matrix contains target
     */
    bool searchMatrix(vector<vector<int>> &matrix, int target) {
        // write your code here
        int nlow = 0, nhigh = matrix.size() - 1;
        while(nlow <= nhigh) {
            int nmid = nlow + (nhigh - nlow) / 2;
            if(matrix[nmid][matrix[nmid].size() - 1] < target) {
                nlow = nmid + 1;
            } else if(matrix[nmid][0] > target) {
                nhigh = nmid - 1;
            } else {
                int mlow = 0, mhigh = matrix[nmid].size() - 1;
                while(mlow <= mhigh) {
                    int mmid = mlow + (mhigh - mlow) / 2;
                    if(matrix[nmid][mmid] < target) {
                        mlow = mmid + 1;
                    } else if(matrix[nmid][mmid] > target) {
                        mhigh = mmid - 1;
                    } else {
                        return true;
                    }
                }
                return false;
            }
        }
        return false;
    }
};

总结

二分法时间复杂度为O(logN).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值