剑指offer面试题:二维数组中的查找,C语言实现
2014-10-27 17:45
555 查看
我是从九度OJ上面看到这个题目的,如果只是简单的想AC这道题目,介于OJ平台只关注输入输出,则很容易AC这道题目。我是把这道题目看做是一道面试题来解决的,先来看下题目吧:
题目描述:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数。
输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字。
接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
输出:
对应每个测试案例,
输出”Yes”代表在二维数组中找到了数字t。
输出”No”代表在二维数组中没有找到数字t。
下面来分析一下思路:
首先,因为数组的每一行和每一列都是递增的所以可以发现如下的规律:
数字7是大矩阵的最小值,13是小矩阵的最小值,所以我们的思路就是先让查找的数x跟二维数组的对角线上的值进行比较(找到数组中对角线上第一个大于x的数的位置来缩小查找的范围)比如,我们查找12,那么查找的范围就可以锁定在两个部分,如下图所示:
此时,我们只要在这两部分中查找x即可,观察可发现这两个部分一个是一行数据(可视为一维数组)和一个是小矩阵。前一部分可以用二分查找(有序),后一部分可以直接遍历(应该还有更好的方法,我实现的时候是直接遍历)。
由于题目对m和n的大小关系没有做限制,这就增加了题目的难度(即找到二维数组中第一个大于x的数的位置边困难了),我的解决思路是根据m和n的大小关系分三种情况,
当m=n时最简单,在此不提,另外两种情况,分别是找一个小的方型矩阵,如果没有找到要找的位置,那么改变循环变量的值,继续在下一个小方型矩阵中寻找,直到没有小的方型矩阵为止。下面给出一个m>n的大致查找过程:
主要解题思路如上所述,下面给出C语言实现的完整代码(附注释)
在oj测试,AC通过,可能还有没有考虑到的地方,欢迎指正,共同学习。
题目描述:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数。
输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字。
接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
输出:
对应每个测试案例,
输出”Yes”代表在二维数组中找到了数字t。
输出”No”代表在二维数组中没有找到数字t。
下面来分析一下思路:
首先,因为数组的每一行和每一列都是递增的所以可以发现如下的规律:
数字7是大矩阵的最小值,13是小矩阵的最小值,所以我们的思路就是先让查找的数x跟二维数组的对角线上的值进行比较(找到数组中对角线上第一个大于x的数的位置来缩小查找的范围)比如,我们查找12,那么查找的范围就可以锁定在两个部分,如下图所示:
此时,我们只要在这两部分中查找x即可,观察可发现这两个部分一个是一行数据(可视为一维数组)和一个是小矩阵。前一部分可以用二分查找(有序),后一部分可以直接遍历(应该还有更好的方法,我实现的时候是直接遍历)。
由于题目对m和n的大小关系没有做限制,这就增加了题目的难度(即找到二维数组中第一个大于x的数的位置边困难了),我的解决思路是根据m和n的大小关系分三种情况,
当m=n时最简单,在此不提,另外两种情况,分别是找一个小的方型矩阵,如果没有找到要找的位置,那么改变循环变量的值,继续在下一个小方型矩阵中寻找,直到没有小的方型矩阵为止。下面给出一个m>n的大致查找过程:
主要解题思路如上所述,下面给出C语言实现的完整代码(附注释)
#include<stdio.h> #include<stdlib.h> long a[1000][1000]; int m,n; //二分查找 int binarySearch(int tm1,int tn1,long x) { int s,e,mid; s=tn1+1; e=n-1; while(s<=e) { mid=(s+e)/2; if(a[tm1][mid]==x) return 1; else if(a[tm1][mid]<x) { s=mid+1; } else { e=mid-1; } } return 0; } //小矩阵遍历 int binarySearch2(int tm2,int tn2,long x) { int i,j; for(i=tm2;i<m;++i) for(j=0;j<=tn2;++j) if(a[i][j]==x) return 1; return 0; } int arraySearch(long x) { int tm,tn; int r1,r2; if(m>n) { tm=0; tn=0; //查找位置的过程 while(tm<m) { if(a[tm][tn]==x) { return 1; } if(a[tm][tn]>x) { break; } if(tn==n-1) { tn=0; ++tm;//进入下一个小型方阵 } else { ++tn; ++tm; } } //查找位置的过程 if(tm==m) { return binarySearch(tm-1,0,x); } else { //找到位置后,分别对两部分进行查找 r1=binarySearch(tm-1,tn-1,x);//二分查找 r2=binarySearch2(tm,tn-1,x);//小矩阵遍历 return (r1+r2); } } else if(m<n) { tm=0; tn=0; while(tn<n) { if(a[tm][tn]==x) { return 1; } if(a[tm][tn]>x) { break; } if(tm==m-1) { tm=0; ++tn; } else { ++tn; ++tm; } } if(tn==n) { return binarySearch2(tn-1,0,x); } else { r1=binarySearch(tm-1,tn-1,x); r2=binarySearch2(tm,tn-1,x); return (r1+r2); } } else { tm=0; tn=0; while(tm<m) { if(a[tm][tn]==x) { return 1; } if(a[tm][tn]>x) { break; } ++tn; ++tm; } if(tm==m) { return 0; } else { r1=binarySearch(tm-1,tn-1,x); r2=binarySearch2(tm-1,tn-1,x); return (r1+r2); } } } int main() { int i,j; long x; while(scanf("%d %d",&m,&n)!=EOF) { scanf("%ld",&x); for(i=0;i<m;++i) for(j=0;j<n;++j) { scanf("%ld",&a[i][j]); } if(arraySearch(x)) { printf("Yes\n"); } else { printf("No\n"); } } return 0; }
在oj测试,AC通过,可能还有没有考虑到的地方,欢迎指正,共同学习。
相关文章推荐
- 剑指offer面试题3:二维数组中的查找 java实现
- 《剑指offer》面试题三 二维数组中的查找
- 剑指offer:面试题三:二维数组中的查找
- 剑指Offer 面试题三:二维数组中的查找
- 【C语言】【面试题】【笔试题】二维数组中的查找,杨氏矩阵
- 剑指offer面试题3—二维数组中的查找
- 九度《剑指Offer》面试题3 二维数组中的查找
- 剑指offer_面试题3_二维数组中的查找(简单问题亦不能忽视)
- 剑指offer第一题【二维数组中的查找】c++实现
- 剑指offer:二维数组中的查找 代码实现
- 《剑指offer》面试题3 二维数组中的查找(杨氏矩阵)
- 剑指offer 面试题3 二维数组的查找
- 面试题03_二维数组中查找_剑指offer系列
- 剑指offer面试题3-二维数组中的查找
- 【C语言】【面试题】【笔试题】二维数组中的查找,杨氏矩阵
- 《剑指Offer》面试题-二维数组中的查找
- 剑指Offer:面试题3 二维数组中的查找
- (剑指Offer)面试题3:二维数组中的查找
- 面试题3 二维数组中的查找 java实现
- 剑指offer 数据结构与算法 二维数组查找 java 实现