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

本文探讨了一种二维数组的特殊排列:每一行和每一列都递增。针对这种排列,提出了一种优化查找算法,通过比较目标值与当前行首或列末元素,减少了搜索时间。通过示例解释了算法思路,并提供了C语言实现的查找函数,适用于面试场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

显而易见可以通过遍历数组中所有数据的方法,来找到是否有满足题意的整数。

#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");	
}

剑指offer面试题4-二维数组中的查找.cpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值