剑指offer面试题:二维数组中的查找,C语言实现

我是从九度OJ上面看到这个题目的,如果只是简单的想AC这道题目,介于OJ平台只关注输入输出,则很容易AC这道题目。我是把这道题目看做是一道面试题来解决的,先来看下题目吧:

题目描述:

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

输入:

输入可能包含多个测试样例,对于每个测试案例,

输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数。

输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字。

接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。

输出:

对应每个测试案例,

输出”Yes”代表在二维数组中找到了数字t。

输出”No”代表在二维数组中没有找到数字t。

下面来分析一下思路:

首先,因为数组的每一行和每一列都是递增的所以可以发现如下的规律:

剑指offer面试题:二维数组中的查找,C语言实现_第1张图片

数字7是大矩阵的最小值,13是小矩阵的最小值,所以我们的思路就是先让查找的数x跟二维数组的对角线上的值进行比较(找到数组中对角线上第一个大于x的数的位置来缩小查找的范围)比如,我们查找12,那么查找的范围就可以锁定在两个部分,如下图所示:

剑指offer面试题:二维数组中的查找,C语言实现_第2张图片

此时,我们只要在这两部分中查找x即可,观察可发现这两个部分一个是一行数据(可视为一维数组)和一个是小矩阵。前一部分可以用二分查找(有序),后一部分可以直接遍历(应该还有更好的方法,我实现的时候是直接遍历)。

由于题目对m和n的大小关系没有做限制,这就增加了题目的难度(即找到二维数组中第一个大于x的数的位置边困难了),我的解决思路是根据m和n的大小关系分三种情况,

当m=n时最简单,在此不提,另外两种情况,分别是找一个小的方型矩阵,如果没有找到要找的位置,那么改变循环变量的值,继续在下一个小方型矩阵中寻找,直到没有小的方型矩阵为止。下面给出一个m>n的大致查找过程:

剑指offer面试题:二维数组中的查找,C语言实现_第3张图片

主要解题思路如上所述,下面给出C语言实现的完整代码(附注释)

#include
#include
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]n)
	{
		tm=0;
		tn=0;
		//查找位置的过程 
		while(tmx)
			{
				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(mx)
			{
				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(tmx)
			{
				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

在oj测试,AC通过,可能还有没有考虑到的地方,欢迎指正,共同学习。





你可能感兴趣的:(面试题)