Young氏矩阵查找
一、问题描述
给定一个二维数组,如果这个二维数组满足下面两个条件则称为Young氏矩阵:
1、在这个二维数组的每一行都按照从左到右的顺序递增。
2、在这个二维数组的每一列都按照从上到下的顺序递增。
现在需要完成的功能描述如下:输入Young氏矩阵,并且给定一个要查找的数,判断该数是否在这个Young氏矩阵中。
二、问题分析
这里不讲述遍历这个二维数组来查找该数(时间复杂度为O(row*column))。既然是在Young氏矩阵中查找一个数find_number,那么就一定要用上Young氏矩阵的性质。假设查找到Young氏矩阵数组numbers的第i行第j列,即numbers[i][j],那么来判断一下find_number是否和numbers[i][j]相等。如果相等就找到了。如果find_number>numbers[i][j],根据Young氏矩阵的性质,它需要往下面走或者右面走。如果find_number<numbers[i][j],根据Young氏矩阵的性质,它需要往上面走或者左面走。但是这样就需要考虑两个方向的移动。
那么能不能在查找的过程中只朝着某一个方向移动呢?答案是可以的。这就需要选好第一个查找位置,由于想要只能沿着一个方向移动,那么最开始的位置也只能是二维数组的四个角。那么选择哪一个角呢?假设选择numbers[0][0]这个角的话,如果find_number>numbers[0][0]的话,还是有两个方向可以移动(下和右)。选择numbers[row-1][column-1]这个角的话(row代表二维数组有多少行,column代表二维数组有多少列),如果find_number<numbers[row-1][column-1],也还是有两个方向可以移动(左和上)。
那么,如果我们把初始的查找位置选择成numbers[0][column-1],查找时将只有一个方向可以选择,如果find_number>numbers[i][j],那么查找路径需要向下查找,如果find_number<numbers[i][j],那么查找路径需要向左查找。初始路径选择numbers[row-1][0]时可以做类似的分析。这么一来时间复杂度为O(row+column)。在下面的程序实现时,只给出了初始位置选择numbers[0][column-1]的情形。另一种情况类似。
三、程序实现
//Judge whether a number in a Young Matrix.
#include <iostream>
//#define MAX_BUF 1024
using namespace std;
int main()
{
int row,column;
long find_number = 0;
// int numbers[MAX_BUF][MAX_BUF];
int numbers[100][100];
int i,j;
while(cin>>row>>column)
{
cin>>find_number;
for(i=0;i<row;i++)
for(j=0;j<column;j++)
cin>>numbers[i][j];
int flag = 0;
i = 0;
j = column-1;
while(i<row && j>=0)
{
if(find_number == numbers[i][j])
{
flag=1;
break;
}
else if(find_number < numbers[i][j])
{
j--;
continue;
}
else
{
i++;
continue;
}
}
if(flag==1)
{
cout<<"find"<<find_number<<",the row index:"<<i+1<<",the column index:"<<j+1<<endl;
}
else
{
cout<<"not find "<<find_number<<endl;
}
}
return 0;
}
分析总结:刚开始想当然的开了一个1024*1024的int数组,用sizeof测试int为4byte,那么这个数组需要开辟的内存为4GB,而本机内存为4GB,所以出错了。
四、测试结果