《剑指Offer》 二维数组的查找 C语言版本


前言

参考文章:里面有更好的动画版本

此题为《剑指Offer》第二版算法题。

题目是:

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

示例:

现有矩阵 matrix 如下:

[
[1,   4,  7, 11, 15],
[2,   5,  8, 12, 19],
[3,   6,  9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]

给定 target = 5,返回 true。

给定 target = 20,返回 false。

限制:

  • 0 <= n <= 1000
  • 0 <= m <= 1000

题目解析

观察矩阵,可以发现:左下角元素 为所在列最大元素,所在行最小元素

如果 左下角元素 大于了目标值,则目标值一定在该行上方,左下角元素所在行可以消去

如果 左下角元素 小于了目标值,则目标值一定在该列的右方,左下角元素所在列可以消去

具体操作为从矩阵左下角元素开始遍历,并且与目标值对比:

  • row 是行数 column 是列数
  • matrix [row] [column] > target 时:行索引向上移动一格(即 row– ),即消去矩阵第 row 行元素
  • matrix [row] [column] < target 时:行索引向上移动一格(即 column++ ),即消去矩阵第 column 列元素
  • matrix [row] [column] < target 时:返回 true
  • 如果越界,返回 false

图片演示 target = 7

1、从矩阵左下角元素开始遍历,将其与目标值进行对比

146915
2571219
3891622
1013151823
row1819232528
column

2、元素18大于目标值7,行row索引向上移动一格

146915
2571219
3891622
row1013151823
1819232528
column

此时原来的那一行都不符合要求,对原来的行进行消去

146915
2571219
3891622
row1013151823
1819232528
column

3、元素10大于目标值7,行row索引向上移动一格

146915
2571219
row3891622
1013151823
1819232528
column

此时原来的那一行都不符合要求,对原来的行进行消去

4、元素3小于目标值7,列column索引向右移动一格

146915
2571219
row3891622
1013151823
1819232528
column

此时原来的那一列都不符合要求,对原来的列进行消去

5、元素8大于目标值7,行row索引向上移动一格

146915
row2571219
3891622
1013151823
1819232528
column

此时原来的那一行都不符合要求,对原来的行进行消去

6、元素5小于目标值7,列索引向右移动一格

146915
row2571219
3891622
1013151823
1819232528
column

此时原来的那一列都不符合要求,对原来的列进行消去

7、找到目标值,返回true


代码实现

#include <stdio.h>

#define true 1
#define false 0

int Find(int array[][5], int rows, int columns, int num)		//row是原数组行数,columns是原数组列数
{
	int row;		//循环行数(注意没有s)
	int column;		//循环列数 (注意没有s)
	row = 4;		//从最后一行开始
	column = 0;		//从最后一行第一个开始(即左下角)
	if (rows == 0 || columns == 0)
	{
		return false;
	}
	while (column < columns && row >= 0)
	{
		if (array[row][column] == num)
		{
			return true;
		}
		else if (array[row][column] < num)
		{
			column++;		//向右移动
		}
		else
		{
			row--;			//向上移动
		}
	}
	return false;
}
void main()
{
	int row;		//行数
	int column;		//列数
	int num;		//查找目标 target
	int a[5][5] = {
		{1,4,7,11,15},
		{2,5,8,12,19},
		{3,6,9,16,22},
		{10,13,14,17,24},
		{18,21,23,26,30}
	};
	row = sizeof(a) / sizeof(a[0]);			//求行数
	column = sizeof(a[0]) / sizeof(int);	//求列数
	printf("请输入您想要输入的数字:");
	scanf("%d", &num);
	printf("%d  (若为1为查到了,若为0没有查到)", Find(a,row,column,num));
}
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 117
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 117
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值