【剑指offer系列01✨】二维数组中的查找

内容介绍

本系列我将带着大家一起刷剑指offer的题目,欢迎大家一起交流一起讨论⭐️⭐️⭐️,希望能得到大家的👍和🐾🐾

题目介绍:

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

在这里插入图片描述

思路:当任取数组中的一个数字的时候有三种情况:

  1. 当数组中选择的数字刚好等于要寻找的数,则结束寻找
  2. 如果选择的数字小于要查找的数,则要查找的数在该数的右边或下面
  3. 如果选择的数字大于要查找的数,则要查找的数在该数的左边或上面

图解

这样看起来问题还是很复杂的,但是我们会发现如果从数组的角度开始寻找那么就只会向一个方向移动。
我们来举个栗子:比如要在上面的数组例子中寻找7,我们从右上角开始寻找,右上角元素是9,比7大,所以我们寻找的范围就缩小到了前三列(第四列剩下的数必然比7大),然后我们再从缩小的数组的右上角进行寻找,发现是8,所以查找范围变成前两列,这时右上角元素为2,比7小,这时我们把范围缩小为一个3*2的矩阵,此时右上角元素为4,仍然比7小,范围再次缩小为一个2*2的矩阵,右上角元素为7,成功找到我们需要找的数字,查找结束。
注意:这里我们只能从右上角和左下角进行查找,因为这两个数刚好一个方向比它小一个方向比它大,这样才能方便我们缩小范围,如果是左上角,下面和右边都比它大这样就不好缩小范围了,右下角同理

在这里插入图片描述

从分析中我们可以发现一个规律,从右上角开始查找数字,若比目标数字大则范围数组列减一(此时将之前右上角元素列下标减一即可),若比目标数字小则范围数组行加一(此时将之前右上角元素行下标加一即可),直达最终找到我们的目标数字,若最终没找到则说明该数不在数组中。

代码实现:

int Find_num(int* pa, int rows, int cols, int num)
{
	int flag = 0;//标志位,用来判断是否找到数字。
	int row = 0;
	int col = cols - 1;
	if (pa != NULL && rows > 0 && cols > 0)//保证输入都是有效的参数
	{
		while (row < rows && col >= 0)//若不满足条件说明查到到数组范围外了,说明要找的数不在数组里面。
		{
			if (pa[row * cols + col] == num)//二维数组在内存中连续存放,所以可以用首元素地址进行偏移找到二维数组中任意一个元素。
			{
				flag = 1;
				break;
			}
			else if (pa[row * cols + col] > num)
			{
				col--;
			}
			else
			{
				row++;
			}
		}
	}
	return flag;
}
int main()
{

	int i = 0;
	int j = 0;
	int arr[4][4] = { {1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15} };
	int n = 0;
	int* parr = arr[0];
	printf("请输入你要找的数:");
	scanf("%d", &n);
	int ret = Find_num(parr, 4, 4, n);
	if (ret)
	{
		printf("找到了\n");
	}
	else
	{
		printf("没有该数字\n");
	}
	return 0;
}

结果:
在这里插入图片描述
在这里插入图片描述

作者水平有限,若文章有任何问题欢迎私聊或留言,希望和大家一起学习进步!!!
创作不易,再次希望大家👍支持下,谢谢大家🙏

  • 31
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值