有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的
请编写程序在这样的矩阵中查找某个数组是否存在。
要求:时间复杂度小于O(N);
例如:
1 2 3
4 5 6
7 8 9
时间复杂度O(N):N个元素,找其中某一个元素的时间最坏需要N次;
int find_num(int arr[3][3],int row,int col,int k )
{
int x = 0;
int y = col - 1;
while (y>=0 && x<=row-1)
{
if (k < arr[x][y])//要找的值和右上角值的关系
{
y--;
}
else if (k > arr[x][y])
{
x++;
}
else
{
return 1;
}
}
return 0;//找不到
}
int main()
{
int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
int k = 0;
scanf("%d", &k);
int ret = find_num(arr,3,3,k);
printf("%d", ret);
return 0;
}
找到了返回1,没找到返回0
但是,这种算法我们只能判断找没找到,并不能知道它的具体位置。
如果在函数内部打印位置,就破坏了函数单一性。因此利用结构体实现。
struct Point
{
int x;
int y;
};
struct Point find_num(int arr[3][3],int row,int col,int k )
{
int x = 0;
int y = col - 1;
struct Point p = { 0,0 };
while (y>=0 && x<=row-1)
{
if (k < arr[x][y])//要找的值和右上角值的关系
{
y--;
}
else if (k > arr[x][y])
{
x++;
}
else
{
p.x = x;
p.y = y;
return p;
}
}
return p;//找不到
}
int main()
{
int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
int k = 0;
scanf("%d", &k);
struct Point ret = find_num(arr,3,3,k);
printf("%d %d", ret.x,ret.y);
return 0;
}
最后,仍然可以优化,利用指针的返回行传参;
int find_num(int arr[3][3],int*px,int*py,int k )
{
int x = 0;
int y = *py - 1;
while (y>=0 && x<= *px -1)
{
if (k < arr[x][y])//要找的值和右上角值的关系
{
y--;
}
else if (k > arr[x][y])
{
x++;
}
else
{
*px = x;
*py = y;
return 1;
}
}
*px = -1;
*py = -1;
return 0;//找不到
}
int main()
{
int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
int k = 0;
int a = 3;
int b = 3;
scanf("%d", &k);
int ret = find_num(arr,&a,&b,k);
if (ret == 1)
{
printf("%d %d\n", a, b);
}
else
{
printf("找不到");
}
return 0;
}