杨氏矩阵
问题:有一个二维数组,数组的每行从左到右是递增的,数组的每列从上到下是递增的,在这样的数组中查找一个数字是否存在。时间复杂度小于0(N)
例:数组
[1 2 3 [1 2 4
4 5 6 或 2 4 5
7 8 9 ] 7 8 9]
解题方法:通过目标元素与左下角或者右下角的元素比较大小,可快速确定目标元素的坐标位置
分析:元素与一行最左边的数(该行最小,该列最大)或者最右边的数(该行最大,该列最小)进行比较,可排除一行或者一列
注:若该数比最左边的数小(大),则该数不在本行(列),再与上(后)一行(列)的数进行比较,可排除本行(列);若该数比最右边的数小(大),则该数不在本列(行),再与前(下)一列(行)的数进行比较,可排除本列
以下代码仅会显示是否找到目标元素,不会输出目标元素的坐标
#define _CRT_SECURE_NO_WARINGS 1
#include <stdio.h>
int Find(int arr[3][3], int row, int col, int k)
{
//右上角的数的坐标[x][y]—>x-行号;y-列号(计算机中计数从0开始,最右边表示的列数要减1,记为 col-1)
int x = 0;
int y = col - 1;
while (x < row && y >= 0) //输入坐标的有效范围,停止条件
{
if (arr[x][y] < k) //不在该行,下一行查找
x++;
else if (arr[x][y] > k)//不在该列,前一列查找
y--;
else //相等,找到了
return 1;
}
return 0;
}
int main()
{
int arr[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int k = 7;
int ret = Find(arr,3, 3, k);//将 Find 的返回值赋给 ret
if (ret == 1)
printf("找到了\n");
else
printf("找不到\n");
system("pause");
return 0;
}
以下代码既能显示是否找到目标元素,也能输出目标元素的坐标
#define _CRT_SECURE_NO_WARINGS 1
#include <stdio.h>
int Find(int arr[3][3], int row, int col, k)
int Find(int arr[3][3], int *px, int *py, int k)
{
//右上角的数的坐标[x][y]—>x-行号;y-列号(计算机中计数从0开始,最右边表示的列数要减1,记为 col-1)
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; //通过指针传x,y
*py = y;
return 1;
}
}
return 0;
}
int main()
{
int arr[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int k = 7;
int x = 3;
int y = 3;
int ret = Find(arr, &x, &y, k);//返回行参数 //将 Find 的返回值赋给 ret
if (ret == 1)
printf("找到了:%d %d\n",x ,y);
else
printf("找不到\n");
system("pause");
return 0;
}