题目:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个证书,判断数组中是否含有该整数。
显而易见可以通过遍历数组中所有数据的方法,来找到是否有满足题意的整数。
#include <stdio.h>
#define N 100
int input[N][N];
int num;
int m,n;
int main()
{
scanf_s("%d%d%d",&num,&m,&n); //输入待查找的数字 以及二维数组的行与列
int i,j = 0;
for(i = 0;i < m;i++)
{
for(j = 0;j < n;j++)
{
scanf_s("%d",&input[i][j]);
}
}
// 获取输入的数组
for(i = 0;i <m;i ++)
{
for(j = 0;j<n;j++)
{
if(input[i][j] == num)
{
printf("YES\n");
return 1;
}
}
}
printf("NO\n");
return 0;
}
这种方法容易想到也容易实现,而且具有普适性。就是对于容量很大的数组来说,计算速度会慢。而且很多面试官也不喜欢这样的答案,因为没有用到题目中给出的条件。已知条件一:每一行都按照从左到右递增的顺序排序;已知条件二:每一列都按照从上到下递增的顺序排序。如何利用这两个条件来优化代码的运算速度,减少计算量呢。
先根据题目要求假设这样一个二维数组:
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
因为每一行都是从小到大,那么就是说,每一行的最左边的数,是这一行里最小的数。如果我们需要查找的数字,比这一行最左边的数字还要小,那就是说这一行肯定没有我们需要查找的数字,这样就可以节约一行的计算量。比如我们需要查找2这个数字。先从第四行 4 5 6 7中最左边的数字4开始,2比4要小,那么我们直接跳到上面一行3 4 5 6 中去查找。2还是比3小,我们再跳到上面一行 2 3 4 5,直到可以找到我们需要查找的数字为止。同理我们也可以从右上角开始查找。
先来写一个查找是否存在这样一个数字的函数:
int IsExist(int row,int cols)
{
while(row<m && cols>=0)
{
if(input[row][cols] == num)
{
return 1; // 找到了这样一个数字
}
if(input[row][cols] > num)
{
cols--; // 如果input[row][cols]比我们要查找的数字大,那么就往左移动一列
}
if(input[row][cols] < num)
{
row++; // 如果input[row][cols]比我们要查找的数字小,那么就往下移动一行
}
}
return 0;//如果一直遍历到row大于n或者cols小于0时还没找到,就说明没有这样的数字,返回0
}
这样的话,我们直接在主函数中运行这个函数,根据这个函数的返回值,就可以知道是否存在我们需要查找的这样一个数。
int num;
int m,n;
int input[N][N];
int main()
{
scanf("%d%d%d",&num,&m,&n); //获取待查找的数,二维数组的行与列
for (int i = 0;i <m;i++) //获取数组
{
for(int j = 0;j <n;j++)
{
scanf("%d",&input[i][j]);
}
}
if(IsExist(0,n - 1)) //从第0行第m-1列开始查找 就是右上角
{
printf("Yes\n");
}
else
printf("No\n");
}