前言
大家好,我是熊猫,今天要和大家一起学习的是在杨氏矩阵中寻找数字的问题。
一、题目描述
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。
通过题目描述我们可以得知该矩阵为有序的,每一行、每一列都是从小到大排列的,要在这个矩阵中找数字。
我想很多人看到这里的第一反应就是二分查找,二分查找虽然同样可以解决问题,不过效率并不是最高的,下面我们会介绍包括二分查找在内的两种方法,希望可以为大家带来不同的思路。
二、题目解析
(一)解法1 – 二分查找
二分查找就是用两个下标 left ,right(也可以直接使用指针)一个在最左边一个在最右边,再有一个变量mid 来存放他们两个的中间值,并和我们的目标值进行比较,
相等就结束循环,
如果小于目标值,就把左边的下标移向中间值的左边一位 left = mid + 1;
如果大于目标值,就把右边的下标移向中间值的左边一位 right = mid - 1;
之后要比较left<= right,若果left在right的右边就说明目标值不存在。
每一行都要进行一次。
代码如下(示例):
#include<stdio.h>
#define ROW 4
#define COL 4
int Find(const int arr[ROW][COL],const int row,const int col,const int aim) {
if (aim<arr[0][0] || aim>arr[row - 1][col - 1])//判断是否超过范围
return 0;
for (int i = 0; i < row; i++){
int left = 0;
int right = col - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (aim == arr[i][mid])
return 1;
else if (aim < arr[i][mid])
right = mid - 1;
else
left = mid + 1;
}
}
return 0;
}
int main() {
int n = 0;
while(1){
puts("请输入目标数字:");
scanf("%d", &n);
int arr[ROW][COL] = { 0 };
for (int i = 0; i < ROW; i++){
for (int j = 0; j < COL; j++) {
arr[i][j] = i + j; //设置数组元素,这里为 0~6
printf("%d ", arr[i][j]);
}
printf("\n");
}
if (Find(arr, ROW, COL, n))
printf("存在\n");
else
printf("不存在\n");
}
return 0;
}
(二)解法2 – Step-wise线性搜索解法
这里我们来认识一种很巧妙的方法,我们从右上角开始判断,
相等就结束,
如果这个数字小于目标数字就往下移动一格(行数加一),
如果这个数字大于目标数字就往左移动一格(列数减一),
如果找到最后都没有目标值就结束。
也可以从左下角往右上角进行判断;
这里之所以不使用左上角的值是因为:它是最小值,当目标值比它小的时候当然就可以直接结束,但是当目标值比它大的时候,不能确定是应该往左移动还是往下移动,这会增加判断的难度。
代码如下(示例):
#include<stdio.h>
#define ROW 4
#define COL 4
int Find(const int arr[ROW][COL],const int row,const int col,const int aim) {
if (aim<arr[0][0] || aim>arr[row-1][col-1])
return 0;
int i = 0;
int j = col - 1;
while (i <= row-1 && j >= 0) {//从右上角移动到左下角
if (aim == arr[i][j])
return 1;
else
if (aim > arr[i][j])
i++;
else
j--;
}
return 0;
}
int main() {
int n = 0;
while (1) {
puts("请输入目标数字:");
scanf("%d", &n);
int arr[ROW][COL] = { 0 };
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
arr[i][j] = i + j;
printf("%d ", arr[i][j]);
}
printf("\n");
}
if (Find(arr, ROW, COL, n))
printf("存在\n");
else
printf("不存在\n");
}
return 0;
}
总结
以上就是熊猫对这个题目的理解,本题的解法有很多,如果大家还有其他好的做法欢迎在评论区留言,在此感谢大家对的支持,这是熊猫持续更新的巨大推进力!