题目描述:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
C++代码:
class Solution
{
public:
bool Find(int target, vector<vector<int> > arr)
{
int row = arr.size();//行数
int col = arr[0].size();//列数
if(row == 0 || col == 0)
{
return false;
}
int i = 0,j = col -1;//从右上角开始
while( j >= 0 && i < row ) //不越界
{
if(arr[i][j] == target)//找到,跳出
{
return true;
}
else
{
if(arr[i][j] < target)//目标数大于数组中的数,向下一行
{
++i;
}
else
{
--j;//目标数小于数组中的数,向左一列
}
}
}
return false;
}
};
void main()
{
int b[3][3] = {4,9,10,5,13,17,25,88,99};
vector<vector<int>> a(3,vector<int>(3));
for(int i = 0; i < 3;++i)
{
for (int j = 0; j < 3; ++j)
{
a[i][j]=b[i][j];
}
}
Solution s;
bool temp = s.Find(44,a);
cout<<temp<<endl;
temp = s.Find(17, a);
cout<<temp<<endl;
temp = s.Find(88,a);
cout<<temp<<endl;
}
测试结果:
启示:此题第一反应从左上角开始寻找,但是由于要查找的数字相对于当前选取的位置有可能在两个区域中出现,而且这两个区域还有重叠,这问题看起来就复杂了!
不妨换个思路,从右上角或者左下角的数字开始寻找。如果该数字等于要查找的数字,查找过程结束;如果该数字大于要 查找的数字,剔除这个数字所在的列;如果该数字小于要查找的数字, 除这个数字所在的行。也就是说如果要查找的数字不在数组的右上角,则每次都在数组的查找范围中剔除一行或者一列,这样每一步都可以缩小查找范围,直到找到要查找的数字,或者查找范围为空。