杨氏矩阵
题目:
有一个二维数组
数组的每行从左到右是递增的,每列从上到下是递增的.
在这样的数组中查找一个数字是否存在要求:查找算法时间复杂度小于O(N)
思路:
假设二维数组如下:

我们通过分析可得,右上角的元素是第一行中最大的元素,是最后一列最小的元素,那就可以从这个元素开始分析,假设目标数=11,11>4则11肯定在4的这行,那么行数加一。这时和11比较的数就为8了,11>8,行数再加1,这时和11比较的数为12,而11<12,则11肯定在12的这一行,并且在12的左边,列数减一,这时和目标数比较的数为11,11=11,目标数找到。
ps:左下角的数也有相同性质
代码1:
#include<stdio.h>
// 1 2 3 4
// 5 6 7 8
// 9 10 11 12
// 13 14 15 16
int Find(int arr[4][4], int row, int col, int k) //不用带回目标位置
{
int x = 0;
int y = col - 1; //x和y先定位右上角的元素
while (x <= row-1 && y >= 0) //x在加的过程中要小于行数,y在减小的过程中要大于等于0
{
if (arr[x][y] < k)
x++;
else if (arr[x][y] > k)
y--;
else
return 1;
}
return 0;
}
int main()
{
int arr[4][4] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
int k = 0;
int x = 4;
int y = 4;
printf("请输入要查询的数:");
scanf("%d", &k);
int ret = Find(arr, x, y, k);
if (ret == 1)
printf("YES\n");
else
printf("NO\n");
return 0;
}
代码二:
代码一中的函数只能判断数组中是否存在待查找的数,不能返回目标数在数组中的坐标。
那如果我们既想判断目标数存在不存在,还想知道目标数的坐标怎么实现呢?
在进行函数传参的时候我们需要传入数组的行数和列数,那也可以用这两个数带回来目标数的坐标:将函数形参定义为两个整形指针变量,传入x和y的地址,当找到目标数后,再把坐标赋值给*x和*y,这样就可以把坐标带回来了。
#include<stdio.h>
int Find(int arr[4][4], int* row, int* col, int k) //判断目标是否存在,并且带回坐标
{
int x = 0;
int y = *col - 1;
while (x <= *row - 1 && y >= 0)
{
if (arr[x][y] < k)
x++;
else if (arr[x][y] > k)
y--;
else {
*row = x;
*col = y;
return 1;
}
}
return 0;
}
int main()
{
int arr[4][4] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
int k=0;
int x = 4;
int y = 4;
printf("请输入要查询的数:");
scanf("%d", &k);
int ret = Find(arr, &x, &y, k);
if (ret == 1)
printf("YES,坐标为:%d %d\n",x,y);
else
printf("NO\n");
return 0;
}
文章介绍了如何在一个二维数组中,利用递增特性设计一个时间复杂度小于O(N)的查找算法,同时提供两种代码实现,一种仅判断是否存在,另一种能返回目标数的坐标。
&spm=1001.2101.3001.5002&articleId=133798265&d=1&t=3&u=8732bee05e624059b72e8b44ba324a05)
175

被折叠的 条评论
为什么被折叠?



