前言
有一个数字矩阵,矩阵的每行从左到右是递增的,每一列从上到下也是是递增的,请在此矩阵中查找是否存在某个数字
1、杨氏矩阵是什么?
杨氏矩阵的定义:
例如:一个简单的3阶杨氏矩阵
杨氏矩阵有两个显著的特点:
- 矩阵的每行从左到右是递增的
- 每一列从上到下也是是递增的
2、方法 1
在学完C语言基础阶段的循环、数组、函数相关的知识点后,可以写出最基础的方法:
- 遍历数组的每一个元素
- 判断是否与查找的数字相等
//时间复杂度O(N^2)
void findnum(int a[][3], int num, int hang, int lie)
{
int i = 0;
int j = 3;
for (int i = 0; i < hang; i++)//遍历数组
{
for (int j = 0; j < lie; j++)
{
if (a[i][j] == num)
{
printf("下标是 %d %d\n", i, j);
return;
}
}
}
printf("没有找到数字\n");
}
int main()
{
int a[][3] = { {1,2,3},
{4,5,6},
{7,8,9} };
int num = 8;//要寻找的饿数字
int hang = sizeof(a) / sizeof(a[0]);//数组行数
int lie = sizeof(a[0]) / sizeof(a[0][0]);//数组列数
findnum(a, num, hang, lie);
return 0;
}
结果见下图:
3、方法 2
在学过【初阶数据结构与算法 1】时间复杂度与空间复杂度(1) 后,可值方法1 的时间复杂度,最坏的情况是O(N^2),因此,可以对方法1优化,要充分利用杨氏矩阵的特点,无需遍历每一个元素:
- 以每一行或每一列为单位进行搜索,先从右上角开始搜索,
- 当右上角的数字大于查找数字,则查找数字位于左侧
- 当右上角的数字小于查找数字,则查找数字位于下侧
void findnum(int a[][3], int num)
{
int i = 0;
int j = 3;
while (i<=2 && j>=0 )//循环的限制条件
{
if (a[i][j - 1] < num)//从右上角开始查找
{
i++;//第一行最大比num小,跳到下一行
}
else if (a[i][j - 1] > num)
{
j--;//第一行最大比num大,行不动,列左移
}
else
{
printf("下标是 %d %d\n", i, j-1);
return;
}
}
printf("没有找到数字\n", i, j - 1);
}
int main()
{
int a[][3] = { {1,2,3},
{4,5,6},
{7,8,9} };
int num = 8;//要寻找的饿数字
findnum(a, num);
return 0;
}
方法 2 将时间复杂度优化为O(n),查找速度较快,结果见下图:
总结
C语言还需要多练习,不管自己写的代码是罗嗦了,还是太烂了,也必须要写完,实现题目要求,这是最重要的一步。
第二步就是多看看别人写的代码,学习别人的思路,记录下来写成博客,方便自己复习。
熟能生巧!