题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true;如果查找数字5,由于数组不含有该数字,则返回false。
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
解决思路(一):从右上角开始查
(1)首先选取数组中右上角的数字。如果该数字等于要查找的数字,查找过程结束;
(2)如果该数字大于要查找的数字,踢除这个数字所在的列;
(3)如果该数字小于要查找的数字,剔除这个数字所在的行;
(4)重复(1)-(3)。
也就是说要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔除一行或者一列,这样每一步都可以缩小查找的范围,知道找到要查找的数字,或者查找范围为空。
代码实现:
#include <iostream>
using namespace std;
//面试题3:二维数组中的查找
bool FindNumFromMatrix(int *matrix, int rows, int cols, int num)
{
bool isFound = false;
if(matrix == NULL || rows <= 0 || cols <= 0){ //一定要对特殊输入进行检查
return isFound;
}
int row = 0;
int col = cols - 1;
while(row < rows && col >= 0){
if(matrix[row * cols + col] == num){
isFound = true;
break;
}
else if(matrix[row * cols + col] > num){
col--;
}
else if(matrix[row * cols + col] < num){
row++;
}
}
return isFound;
}
int main()
{
int a[][4] = {1,2,8,9,2,4,9,12,6,7,10,13,6,8,11,15};
int *p = a[0];
int num = 7;
bool res = FindNumFromMatrix(p, 4, 4, num);
if(res){
cout<<num<<" is in matrix!"<<endl;
}
else{
cout<<num<<" isnot in matrix!"<<endl;
}
system("pause");
return 0;
}
解决思路(二):从左下角开始查
(1)首先选取数组中左下角的数字。如果该数字等于要查找的数字,查找过程结束;
(2)如果该数字小于要查找的数字,踢除这个数字所在的列;
(3)如果该数字大于要查找的数字,剔除这个数字所在的行;
(4)重复(1)-(3)。
也就是说要查找的数字不在数组的左下角,则每一次都在数组的查找范围中剔除一行或者一列,这样每一步都可以缩小查找的范围,知道找到要查找的数字,或者查找范围为空。
代码实现:
#include <iostream>
using namespace std;
//面试题3:二维数组中的查找
bool FindNumFromMatrix(int *matrix, int rows, int cols, int num)
{
bool isFound = false;
if(matrix == NULL || rows <= 0 || cols <= 0){ //一定要对特殊输入进行检查
return isFound;
}
int row = rows - 1;
int col = 0;
while(row >= 0 && col < cols){
if(matrix[row * cols + col] == num){
isFound = true;
break;
}
else if(matrix[row * cols + col] < num){
row--;
}
else if(matrix[row * cols + col] > num){
col++;
}
}
return isFound;
}
int main()
{
int a[][4] = {1,2,8,9,2,4,9,12,6,7,10,13,6,8,11,15};
int *p = a[0];
int num = 7;
bool res = FindNumFromMatrix(p, 4, 4, num);
if(res){
cout<<num<<" is in matrix!"<<endl;
}
else{
cout<<num<<" isnot in matrix!"<<endl;
}
system("pause");
return 0;
}
以上的两种方法分别是从数组查找范围的右上角和左下角开始查找,但是不能从左上角和右下角开始查找。以左上角为例,最初数字1位于初始数组的左上角,由于1小于7,那么7应该位于1的右边或者下边。此时我们既不能从查找范围内剔除1所在的行,也不能剔除1所在的列,这样我们就无法缩小查找的范围了。
其实究竟从哪个角开始查还是是具体问题而定,例如我们把题目改为原始矩阵是从左到右递减,从上到下递增,这种情况下就只能从左上角或右下角开始搜索了^_^,所以学习算法,重要的是掌握算法设计的思路,这很重要。