文章目录
前言
此题为《剑指Offer》第二版算法题。
题目是:
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
限制:
- 0 <= n <= 1000
- 0 <= m <= 1000
题目解析
观察矩阵,可以发现:左下角元素 为所在列最大元素,所在行最小元素
如果 左下角元素 大于了目标值,则目标值一定在该行上方,左下角元素所在行可以消去
如果 左下角元素 小于了目标值,则目标值一定在该列的右方,左下角元素所在列可以消去
具体操作为从矩阵左下角元素开始遍历,并且与目标值对比:
- row 是行数 column 是列数
- 当 matrix [row] [column] > target 时:行索引向上移动一格(即 row– ),即消去矩阵第 row 行元素
- 当 matrix [row] [column] < target 时:行索引向上移动一格(即 column++ ),即消去矩阵第 column 列元素
- 当 matrix [row] [column] < target 时:返回 true。
- 如果越界,返回 false。
图片演示 target = 7
1、从矩阵左下角元素开始遍历,将其与目标值进行对比
1 | 4 | 6 | 9 | 15 | |
---|---|---|---|---|---|
2 | 5 | 7 | 12 | 19 | |
3 | 8 | 9 | 16 | 22 | |
10 | 13 | 15 | 18 | 23 | |
row | 18 | 19 | 23 | 25 | 28 |
column |
2、元素18大于目标值7,行row
索引向上移动一格
1 | 4 | 6 | 9 | 15 | |
---|---|---|---|---|---|
2 | 5 | 7 | 12 | 19 | |
3 | 8 | 9 | 16 | 22 | |
row | 10 | 13 | 15 | 18 | 23 |
18 | 19 | 23 | 25 | 28 | |
column |
此时原来的那一行都不符合要求,对原来的行进行消去
1 | 4 | 6 | 9 | 15 | |
---|---|---|---|---|---|
2 | 5 | 7 | 12 | 19 | |
3 | 8 | 9 | 16 | 22 | |
row | 10 | 13 | 15 | 18 | 23 |
column |
3、元素10大于目标值7,行row
索引向上移动一格
1 | 4 | 6 | 9 | 15 | |
---|---|---|---|---|---|
2 | 5 | 7 | 12 | 19 | |
row | 3 | 8 | 9 | 16 | 22 |
column |
此时原来的那一行都不符合要求,对原来的行进行消去
4、元素3小于目标值7,列column
索引向右移动一格
4 | 6 | 9 | 15 | ||
---|---|---|---|---|---|
5 | 7 | 12 | 19 | ||
row | 8 | 9 | 16 | 22 | |
column |
此时原来的那一列都不符合要求,对原来的列进行消去
5、元素8大于目标值7,行row
索引向上移动一格
4 | 6 | 9 | 15 | ||
---|---|---|---|---|---|
row | 5 | 7 | 12 | 19 | |
column |
此时原来的那一行都不符合要求,对原来的行进行消去
6、元素5小于目标值7,列索引向右移动一格
6 | 9 | 15 | |||
---|---|---|---|---|---|
row | 7 | 12 | 19 | ||
column |
此时原来的那一列都不符合要求,对原来的列进行消去
7、找到目标值,返回true
代码实现
#include <stdio.h>
#define true 1
#define false 0
int Find(int array[][5], int rows, int columns, int num) //row是原数组行数,columns是原数组列数
{
int row; //循环行数(注意没有s)
int column; //循环列数 (注意没有s)
row = 4; //从最后一行开始
column = 0; //从最后一行第一个开始(即左下角)
if (rows == 0 || columns == 0)
{
return false;
}
while (column < columns && row >= 0)
{
if (array[row][column] == num)
{
return true;
}
else if (array[row][column] < num)
{
column++; //向右移动
}
else
{
row--; //向上移动
}
}
return false;
}
void main()
{
int row; //行数
int column; //列数
int num; //查找目标 target
int a[5][5] = {
{1,4,7,11,15},
{2,5,8,12,19},
{3,6,9,16,22},
{10,13,14,17,24},
{18,21,23,26,30}
};
row = sizeof(a) / sizeof(a[0]); //求行数
column = sizeof(a[0]) / sizeof(int); //求列数
printf("请输入您想要输入的数字:");
scanf("%d", &num);
printf("%d (若为1为查到了,若为0没有查到)", Find(a,row,column,num));
}