杨氏矩阵

杨氏矩阵

有一个二维数组. 数组的每行从左到右是递增的,每列从上到下是递增的,在这样的数组中查找一个数字是否存在。 要求:时间复杂度小于O(N)
例如:
每一行逐个增大,每一列也逐个增大。
在这里插入图片描述
现要求在杨氏矩阵中找一个数 k ,要求为:时间复杂度小于O(N)。
(在一个N个元素的二维数组中查找一个元素,最坏的情况是查找N次,时间复杂度为O(N))
这样子就不能在数组中逐个查找。

解析

现创建一个数组符合杨氏矩阵,arr[3][3]= {1, 2, 3, 4, 5, 6, 7, 8, 9};
在这里插入图片描述

可观察数组右上角的元素的特点:为一行中最大的元素,为一列中最小的元素。
当要查找的元素k > arr[j][i]时,说明 k 不在第 j 行,从第 j + 1 行开始找;当 k < arr[ j ][ i ]时, 说明 k 不在 i 列,从第 i - 1列开始找。

假设要查找的元素为k = 7;则从数组右上角开始找。
因为k = 7 > arr[0][2] = 3, 所以 k 不在第0行。
在这里插入图片描述

因为 k = 7 > arr[1][2] = 6, 所以 k 不在第1行。
在这里插入图片描述

因为 k = 7 < arr[2][2] = 9, 所以 k 不在第 2 列。
在这里插入图片描述

因为 k = 7 < arr[2][1] = 8, 所以 k 不在第 1 列。
在这里插入图片描述
最后 k = 7 = arr[2][0] = 7

代码

先写出主函数

int main()
{
	int arr[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  // 创建杨氏矩阵 arr数组
	int ret = FindRound(arr, 3, 3, 7);   //找到了返回1, 没找到返回0
	printf("%d\n", ret);   //打印结果
	return 0;
}

再写FindRound()

//x、y为下标,key为要找的元素
int FindRound(int arr[][3], int x, int y, int key)
{ }

从arr[0][2]开始找

int FindRound(int arr[][3], int x, int y, int key)
{
	int i = 0;
	int j = y - 1;
	while (i < x && j >= 0)  //当数组越界时,, 跳出循环
	{
	}
	return 0; //找不到时返回0
}

逐行/列查找

//x、y为下标,key为要找的元素
int FindRound(int arr[][3], int x, int y, int key)
{
	int i = 0;
	int j = y - 1;
	while (i < x && j >= 0)  //当数组越界时,, 跳出循环
	{
		if (arr[i][j] < key)  //跳到下一行查找
			i++;
		else if (arr[i][j] > key)  //跳到上一列查找
			j--;
		else
		{
			printf("arr[%d][%d] = %d\n", i, j, key);  //找到了打印元素
			return 1;  //找到了返回1
		}
	}
	return 0;  //找不到时返回0
}

运行

k = 7 找到
在这里插入图片描述
k = 11 没找到
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值