牛客网剑指offer-在二维数组中的查找
来源:互联网 发布:mac os官方下载 编辑:程序博客网 时间:2024/06/05 16:05
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
题目解答分析
失败解答1:用二维遍历
这个题要是按普通的二维遍历来查找的话,也能完成功能,但是就体现不出二维数组原先有序的优势了。
如果数组非常大的话,会特别浪费时间。
但是我做的时候还是首先采取了这个二维遍历的方法,因为我开始想的是,我需要读入所有的数据,也只能一个一个读,这已经是一个二维遍历,那就只好在读的时候顺便进行查找了。
程序如下:
程序尝试1:双层循环#include <iostream>using namespace std;int main(int argc, char* argv[]){ int row = 0, col = 0, t = 0; int testNum[100][100]; bool isFound = false; while(cin >> row >> col >> t) { isFound = false; for(int i = 0; i < row ; ++i) { for(int j = 0; j < col; ++j) { //输入每个数 cin>>testNum[i][j]; //边输入边验证 if(false == isFound && t == testNum[i][j]) { //已经找到后就没必要再找了 isFound = true; } } } if(true == isFound) { cout << "Yes" << endl; } else { cout << "No" << endl; } } return 0;}
果然提交以后就显示Time Limit Exceed了。
想必,未显示的测试用例中必然有很大的二维数组。
进一步思考:利用数组有序特点
所以题目给的有序的条件是必须要用的,但是注意到这个有序也不是单纯的有序,行与行之间也只是上面的元素比下面的元素小的关系,并不代表第二行的数一定大于第一行,比如第一行可以是1,2,3,4,而第二行可以是2,3,4,5。
先定位行再定位列的想法也不行,因为不论是第一列还是最后一列,都不足以作为本行的键值,因为各行之间的元素还是可能重叠的。而且,比如,目标值t有可能比第一列的所有元素都大,所以想根据第一个元素来查找是不行的。
书中的思路:
从数组中选取数字,和目标数字的关系有三种情况:=,<或>。
如果是等于则查找成功;
如果是数组中元素小于要查找的数字,说明要查找的数字应该在当前位置的右边或下边。
如果是数组中元素大于要查找的数字,说明要查找的数字应该在当前位置的左边或上边。
但是这两个区域还有可能有重叠,比如右边或下边会在右下角有重叠。
解决方法:
如果查找从右上角开始,如果要查找的数字不在右上角,则每次可以剔除一列或一行。
也可以从左下角开始,但是不能从左上角或者右下角开始。
别人的解答
http://www.cnblogs.com/remlostime/archive/2012/11/21/2780352.html
于是搜到了如上的解答。
可见这个查找是从矩阵的右上角开始进行的(本行最大,本列最小);
如果查找成功,则返回;
如果查找失败,矩阵元素值比t小则下移一行,矩阵元素值比t大则左移一列。
这样把大小关系和调整的两个方向就分开了,经过一些移动,如果查找成功则返回Yes,如果矩阵走完,则表明没有找到。
这样是可以实现(实现代码附在后面),可以通过本文所列的测试用例,但是提交到九度上,还是超时了。
暂时没有解决办法,先休息吧,很晚了。。
解答方法2#include <iostream>using namespace std;int main(int argc, char* argv[]){ int row = 0, col = 0, t = 0; int testNum[1000][1000]; bool isFound = false; while(cin >> row >> col >> t) { //先将数组全部读入 for(int i = 0; i < row ; ++i) { for(int j = 0; j < col; ++j) { //输入每个数 cin>>testNum[i][j]; } } //标志变量,记录查找是否成功 isFound = false; //然后进行查找 for(int i = 0, j = col -1; false == isFound && i < row && j >= 0;) { //找到之后循环就不必再进行 if(testNum[i][j] == t) { isFound = true; } else if(testNum[i][j] < t) { ++i; //换到下一行 } else { --j; //换到前一列 } } //最后输出结果 if(true == isFound) { cout << "Yes" << endl; } else { cout << "No" << endl; } } return 0;}
参考九度的博客
#include <iostream>#include <cstdio>using namespace std;string search(int a[][1000], int m, int n, int key){ int i = 0; int j = n - 1; while(i < m && j >= 0) { if (a[i][j] == key) return "Yes"; else if (a[i][j] < key) i++; else j--; } return "No";}int main(){ int n, m; int a[1000][1000]; while(scanf("%d%d", &m, &n) != EOF) { int key; scanf("%d", &key); for(int i = 0; i < m; i++) for(int j = 0; j < n; j++) scanf("%d", &a[i][j]); cout << search(a, m, n, key) << endl; }}
- 牛客网剑指offer-在二维数组中的查找
- 牛客网剑指offer编程题--二维数组中的查找
- 剑指offer-->二维数组中的查找
- 剑指offer之二维数组中的查找
- 剑指offer:3-二维数组中的查找
- [剑指Offer]二维数组中的查找
- 【剑指offer】二维数组中的查找
- [剑指Offer]二维数组中的查找
- 剑指Offer:二维数组中的查找
- 【剑指offer】二维数组中的查找
- 剑指offer 1384 二维数组中的查找
- 剑指Offer之二维数组中的查找
- 剑指offer 03:二维数组中的查找
- 剑指offer(2) - 二维数组中的查找
- 剑指offer-二维数组中的查找
- 剑指offer-3 二维数组中的查找
- 剑指Offer之 - 二维数组中的查找
- 剑指offer 3 -二维数组中的查找
- day_17_可重入函数、线程同步
- 脚本文件
- Docker容器化快速构建多集群以太坊网络并部署智能合约
- 大二,唤醒 大三,coming
- 使用Rancher搭建K8S测试环境
- 牛客网剑指offer-在二维数组中的查找
- 7.18学习bootstrap之路!
- MySQL登陆的相关命令
- 【PAT】【Advanced Level】1026. Table Tennis (30)
- FZU Problem 2271 X(最短路)
- 高性能可扩展mysql(执行计划,索引分析优化改写,删除重复数据,区间统计,满查询日志)
- 三分法
- [Android] AudioEffect架构:从上层调用到底层音效驱动
- TensorFlow手写识别