目录
补充说明:时间复杂度小于O(N) 是什么意思?
如果此数组有n 个元素,那么在找其中某一个元素时,在其最坏的情况下找了n 次才找到,此时的时间复杂度便是O(N);
同样说明,此处不能采用利用循环来遍历查找;
根据杨氏矩阵的要求,我们可以尝试创建一个杨氏矩阵:
如下图:
我们可以发现每一行最左边的数字在此行中最小,而最右边的数字在此行中最大;每一列的最上面的数字在此列中最小,而最下面的数字在此列中最大;
那么右上角的数字是该行中最大,该列最小的数字;同理,左下角的数字是改行最小,该列最大的数字;
以右上角的数字为例,将右上角的数字与所要查找的数字作比较,当此右上角的数大于所要查找的数字,而此右上角的数字是该列中最小的数字,即说明该列中的数字均大于所要查找的数字,于是乎就排除了该列;而如果此右上角的数字小于所要查找的数字,而右上角的数字是该行中最大的数字,说明该行中的数字均比所要查找的数字小,便可以排除此行;而若右上角的数字等于所要排查的数字,则说明找到该数字了;
代码如下:
#include<stdio.h>
int find_num(int arr[][4], int* px, int* py,int k)//二维数组传参,可以用二维数组来接收,也可以用一维数组指针来接收
{
//右上角的数是此行中最大的数,此列中最小的数;所以将右上角的数与所排查的数进行比较,便可以排除一行或者一列,极大地提高了效率
int x = 0; //从0行开始
int y = *py-1;//从最后一列开始
while (x<= *px && y >= 0)//在查找范围之内继续查找
{
if (arr[x][y] > k)//排除该列
y--;
else if (arr[x][y] < k)//排除该行
x++;
else
{
*px = x;
*py = y;
return 1;
}
}
//走完以上循环没有返回,说明在此范围之内没有找到k
*px = -1;
*py = -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 x = 4;
int y = 4;
int k = 0;
scanf("%d", &k);
int ret =find_num(arr, &x, &y,k);//依靠传址调用将坐标的信息带回来
if (ret)
printf("找到了\n");
else
printf("没找到\n");
printf("%d %d\n", x, y);
return 0;
}
代码运行结果如下:
-
小结
所采用查找的方式比较一次便排除了一行或者一列的数据,极大地提高了效率;运用此种方式查找的时间复杂度也必然小于O(N);
将所要查找的数与左下角的数进行比较也可;