二维有序矩阵的查找
来源:互联网 发布:conoha绑定域名 编辑:程序博客网 时间:2024/05/21 10:37
A. 问题描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
B. 问题分析
其实笨方法有很多种啦:
* 全部无脑遍历一次,时间复杂度为O(NM)
* 对每行/列做二分查找,时间复杂度为O(Nlog M)
* 好像还不够好,可以整体用二分吗?
我们来看一个性质,对于一个N*M的如题所述的矩阵A,如果存在某个值等于要找的target值,看A的最右上角的元素key = A[0][M-1],从这个位置每步向左走或向下走,必定存在一条路径到达target。
所以关键是如何走出这样一条路径出来?
其实需要先对矩阵的性质有一个了解。如下图所示,注意区域2只有一个元素,就是当前矩阵的右上角的位置,很明显,区域1的所有值都是不大于key(即区域2的值),而区域4的所有值都是不小于key的,区域3的元素的值与key暂时没有明确的关系。
不过上面的性质已经足够加快很多了!!!
1. 如果target = key,那么就找到咯!
2. 比如发现target > key,那么明显区域1和2都没必要继续搜索了,对不对?现在需要搜索的矩阵变成了区域3和区域4组成的新的子矩阵了!!!
3. 反之,如果target < key,那么也很明显,区域2和区域4就没必要搜索了,接下来只需要搜索区域1和区域3组成的子矩阵即可!
所以,总的来说,这个算法的复杂度为O(N + M),应该能够很容易分析出来吧?
C. 代码实现
class Solution {public: bool Find(vector<vector<int> >& array, int target) { if (array.empty()) return false; int rowSize = array.size(), colSize = array[0].size(); int x = 0, y = colSize - 1; while (check(0, rowSize, x) && check(0, colSize, y)) { if (target == array[x][y]) return true; else if (target < array[x][y]) --y; else ++x; } return false; } bool check(int lower, int upper, int now) { return now >= lower && now < upper; }};
D. 还有更快的算法吗?
应该是有的,不过有点复杂,思路是——在对角线上做二分查找,然后递归下去,这样的话,分治收敛得更快,有兴趣的可以实现出来交流一下,我等下次回来再实现。【未完待续】
参考:July的《编程之法》4.2节
- 二维有序矩阵的查找
- 二维有序矩阵(杨氏矩阵)的二分查找
- 有序二维数组的查找
- 有序二维数组的查找
- 关于有序二维矩阵查找和字符串替换的两道算法题
- 在行列分别有序的二维矩阵中查找是否有给定值
- 有序的二维数组的查找问题
- 面试题 -- 有序二维数组的查找
- 行列有序的二维数组查找
- 二维有序数组的查找 python解决
- 二维有序数组查找
- 二维有序数组查找
- 二维有序数组查找
- 有序矩阵查找
- 有序矩阵查找练习题
- 有序矩阵查找练习题
- 有序矩阵查找
- 二维有序数组中查找
- java transient简介
- hud1875
- JAVA多线程之高级部分
- Yii2.0 插入多条记录操作中,旧的属性值影响插入操作的原因
- 一个国外博士生Andrews Sobral收集和测试的64个低秩+稀疏矩阵/张量分解的算法库
- 二维有序矩阵的查找
- 【HPU】[1735]老王修马路(一)
- 2015 UESTC Training for Dynamic Programming N - 导弹拦截 LIS nlog(n)+打印字典序最小的路径
- 字符编码笔记:ASCII,Unicode和UTF-8
- Windows下80端口被进程System&PID=4占用
- POJ 2653 Pick-up sticks【计算几何入门】
- if与switch的小区别
- SDWebImage内部实现过程
- 三目运算、可选类型