题目要求:
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的
请编写程序在这样的矩阵中查找某个数字是否存在。
要求:时间复杂度小于O(N);
假设该数字矩阵是:
1 2 3
4 5 6
7 8 9
然后先上代码:
#include <stdio.h>
int find_num(int arr[3][3], int*px, int*py, int k)
{
int x = 0;
int y = *py - 1;
while (x < *px && y >= 0)
{
if (arr[x][y] < k)
{
x++;
}
else if (arr[x][y] > k)
{
y--;
}
else
{
*px = x;
*py = y;
return 1;//找到了
}
}
return 0;//找不到
}
int main()
{
int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
int k = 7;
//如果找到返回1, 找不到返回0
int x = 3;//行
int y = 3;//列
//&x,&y
//1. 传入参数
//2. 带回值
int ret = find_num(arr, &x, &y, k);
if (ret == 1)
{
printf("找到了\n");
printf("下标是:%d %d\n", x, y);
}
else
{
printf("找不到\n");
}
由于题目的条件,是时间复杂度小于0(N),所以我们不采用两个for循环的方法。
如图所示,然后我们可以根据这个原理来设计代码:
int find_num(int arr[3][3], int*px, int*py, int k)
{
int x = 0;
int y = *py - 1;
while (x < *px && y >= 0)//防止越界访问
{
if (arr[x][y] < k)
{
x++;//跳过一行
}
else if (arr[x][y] > k)
{
y--;//跳过一列
}
else
{
*px = x;
*py = y;//输出该元素的下标
return 1;//找到了
}
}
return 0;//找不到
}
只要了解这个思路,代码很简单,但是有一个注意事项:
如果我们要打印该元素的下标,那么我们就要在主函数创建一个x和y,将其赋值为行数和列数,此时的作用在fine_num还是中是传递参数,而将参数的值设为&x和&y,是为了在fine_num函数中,将值带回到主函数中,所以就达到了打印元素地址的目的。
以上是我的分享,谢谢大家。
参考资料:
Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .
比特科技. C语言基础[EB/OL]. 2021[2021.8.31]. .