一些闲话:
小编打算给这个刷题系列改个名,以后就用日期做标题吧,哪一天写了就写哪一天的日期,
不然就跑题了,你说是吧!啊啊啊,根本做不到每日一题!!~~>_<~~
一、题目名称
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。
二、思路分析:
由于矩阵的每行从左到右是递增的,矩阵从上到下也是递增的,所以我们可以从矩阵右上角开始查找。
从右上角开始寻找的话
- 如果当前元素大于目标元素的话,就可以排除当前列,往左移动一列继续寻找;
- 如果当前元素小于目标元素的话,就可以排除当前行,往下移动一行继续寻找;
比如说一个矩阵
1 4 7 11
2 5 8 12
3 6 9 13
10 14 18 22
1、如果目标元素是8,我们从右上角开始寻找,
右上角数字是11,大于8,则根据矩阵从上到下是递增的,我们可以知道11所在列的数字均大于11,都比目标元素8大,所以最后一列就可以直接排除,向左移动一列进行查找。
2、如果目标元素是13,我们从右上角开始寻找,
先看右上角数字11,小于13,根据矩阵每行从左向右是递增的,则最右边的元素是该行最大的数字,因此第一行元素都比目标元素小,第一行元素就可以直接排除,向下移动一行进行查找。
重复上述步骤,直到找到目标数字或者遍历完整个矩阵。
三、代码思路:
1、掌握如何声明和初始化二维数组用来表示数字矩阵
例如:int array[ ][4] = {{1,7,13,19},{3,9,15,21},{5,11,17,23},{10,16,22,28}},声明一个4行4列的矩阵
2、使用循环来查找目标元素
本题可以使用while循环来查找元素,不断根据当前元素与目标数字的大小关系调整查找位置,直到找到目标数字或者遍历完整个矩阵。while循环的条件是查找范围要在矩阵内。
3、使用条件判断
如果当前元素大于目标数字,则往左移动一列继续查找;如果当前元素小于目标数字,则往下移动一行继续查找;如果当前元素等于目标数字,则表示找到了目标数字。
4、定义一个函数findarray
该函数用来实现查找目标元素。
四、代码实现
#include <stdio.h>
//row是行数,col是列数
//rows是矩阵总行数,cols是矩阵总列数
int findarray(int array[][4], int rows, int cols, int target)
{
int row = 0;//表示从第一行开始查找
int col = cols - 1;//表示从最后一列开始查找
while (row < rows && col > 0)//确保查找范围在矩阵内
{
if (array[row][col] == target)//找到了
{
return 1;
}
else if (array[row][col] > target)
{
col--;//向左移动一列
}
else
{
row++;//向下移动一行
}
}
return 0;
}
int main()
{
int array[][4] = { {1,7,13,19},{3,9,15,21},{5,11,17,23},{10,16,22,28} };
int target = 9;
scanf("%d", &target);
int result = findarray(array, 4, 4, target);//调用函数来实现元素查找,并返回值
if (result)
{
printf(" %d 在矩阵中\n", target);
}
else
{
printf(" %d 不在矩阵中\n", target);
}
return 0;
}
结果展示:
五、部分代码分析:
查找部分代码分析:
- while (row < rows && col > 0)循环用于在矩阵中进行查找。只要当前行索引小于行数,且列索引大于等于 0,循环就会继续。
- 如果当前位置的元素array[row][col]等于目标数字target,则直接返回 1,表示找到了目标数字。
- 如果当前位置的元素大于目标数字,说明目标数字不可能在当前列中,因为每列从上到下是递增的。所以将列索引减一,即 col--,向左移动一列继续查找。
- 如果当前位置的元素小于目标数字,说明目标数字不可能在当前行中,因为每行从左到右是递增的。所以将行索引加一,即row++,向下移动一行继续查找。
六、扩展:使用指针来改写代码
不知大家是否还记得前面小编介绍的数组传参的本质这一篇中说到二维数组传参吗?
二维数组传参传递的是一维数组的地址,所以本道题我们可以使用指针来改写一下
#include <stdio.h>
int findarray(int (*array)[4], int rows, int cols, int target)
{
int row = 0;
int col = cols - 1;
while (row < rows && col >= 0)
{
if (array[row][col] == target)
{
return 1;
}
else if (array[row][col] > target)
{
col--;
}
else
{
row++;
}
}
return 0;
}
int main()
{
int array[][4] = { {1,7,13,19},{3,9,15,21},{5,11,17,23},{10,16,22,28} };
int target;
scanf("%d", &target);
int result = findarray(array, 4, 4, target);
if (result)
{
printf("%d 在矩阵中\n", target);
}
else
{
printf("%d 不在矩阵中\n", target);
}
return 0;
}