杨氏矩阵
有一个二维数组.
数组的每行从左到右是递增的,每列从上到下是递增的.
在这样的数组中查找一个数字是否存在。
要求:时间复杂度小于O(N);
例: 1 2 3
4 5 6
7 8 9
这里时间复杂度O(N) = row + col; //行数+列数
要使时间复杂度小于O(N),则必须从右上角开始走或者从左下角开始,如图所示,最长也是5,小于行数+列数
这里就这两种策略来写,分别采用递归和非递归的方式:
我在代码中写了4个函数皆可实现要求:
1. Seek1(); //非递归 右上角开始找
2. Seek2(); //非递归 左下角开始找
3. Sreach1(); //递归 右上角开始找
4. Sreach2(); //递归 左下角开始找
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
//1.从右上角开始找:
// 如果目标值大于当前值,向下找;小于,向左找
void Seek1(int arr[ROW][COL], int key, int *px, int *py)
{
int i = 0;
int j = COL - 1;
while ((i < ROW) && (j >= 0))
{
if (arr[i][j] == key)
{
*px = i;
*py = j;
return;
}
else if(arr[i][j] < key)
{
i++;
}
else
{
j--;
}
}
*px = -1;
}
//2.从左下角开始找:
//如果目标值大于当前值,向右找;小于,向上找
void Seek2(int arr[ROW][COL], int key, int *px, int *py)
{
int i = ROW - 1;
int j = 0;
while ((i >= 0) && (j < COL))
{
if (arr[i][j] == key)
{
*px = i;
*py = j;
return;
}
else if (arr[i][j] < key)
{
j++;
}
else
{
i--;
}
}
*px = -1;
}
//递归 右上角开始找
int Sreach1(int arr[ROW][COL], int key, int *px, int *py, int i, int j)
{
// 出口
if ((i >= ROW) || (j < 0))
{
// 没有找到,px赋值为-1,返回0
*px = -1;
return 0;
}
if (arr[i][j] == key)
{
*px = i;
*py = j;
// 找到了,px,py赋值坐标,返回1
return 1;
}
else if (arr[i][j] > key)
{
// 如果当前值大于key,向左走,找更小的值
return Sreach1(arr, key, px, py, i, j - 1);
}
else
{
// 如果当前值小于key,向下走,找更大的值
return Sreach1(arr, key, px, py, i + 1, j);
}
}
//递归 左下角开始找
int Sreach2(int arr[ROW][COL], int key, int *px, int *py, int i, int j)
{
// 出口
if ((i < 0) || (j >= COL))
{
// 没有找到,px赋值为-1,返回0
*px = -1;
return 0;
}
if (arr[i][j] == key)
{
*px = i;
*py = j;
// 找到了,px,py赋值坐标,返回1
return 1;
}
else if (arr[i][j] > key)
{
// 如果当前值大于key,向上走,找更小的值
return Sreach2(arr, key, px, py, i - 1, j);
}
else
{
// 如果当前值小于key,向右走,找更大的值
return Sreach2(arr, key, px, py, i, j + 1);
}
}
Is_find(int px, int py)
{
if (px != -1)
{
printf("找到了!数组下标为:%d,%d\n", px, py);
}
else
{
printf("没找到!\n");
}
}
int main()
{
int arr[ROW][COL] = { {1,2,3},{4,5,6},{7,8,9} };
int px = 0;
int py = 0;
int i = 0;
int j = 0;
int key = 0;
scanf("%d", &key);
Seek1(arr, key, &px, &py);//非递归 右上角开始找
Is_find(px, py);
Seek2(arr, key, &px, &py);//非递归 左下角开始找
Is_find(px, py);
Sreach1(arr, key, &px, &py, 0, COL - 1);//递归 右上角开始找
Is_find(px, py);
Sreach2(arr, key, &px, &py, ROW - 1, 0);//递归 左下角开始找
Is_find(px, py);
system("pause");
return 0;
}
结果展示: