题目:在一个二维数组中,每一行从左到右递增,每一列从上到下递增,在这个二维数组中,查找给定的数是否存在。
分析:遍历来查找的事这里就不说了,像星爷说的:“像我这么理智的人,怎么会相信这么无稽的事情。”
这本书里提倡,遇到问题画画图,写写小例子。我们把已知条件都在例子中一一标出来。
行递增,列递增,同一颜色按箭头方向,即顺时针方向递增有序,对于圈出的副对角线元素,对于所在行,是该行最大的,对于所在列,是列里最小的,所以它就是中间点(对于同一颜色的部分)。
所以我们觉得在负对角线上的元素位开始,会取得不错的效果,那么这些对角元素效果都一样吗?也就是可以从任意的对角元素开始,还是对他们还有其他的要求?
首先看下右上角的对角元素 9,若查找的数比 9 大,那么可以看出,9 所在的这行就不需要查找了(它是该行最大),就可以跳过一整行,若查找的数比9小,9 所在的列就不需要查找了(它是该行最小的),所以这样就可以整行整列的跳。
再看下绿色的9,若查找的元素比9大,那么我们该这么走呢?是向上还是向左,这就存在二义性,难道要先向左,再向上?好吧,即使这样可以找到,但是相比红色的9还是要麻烦。
7的情况类似。
我们再看下左下角的6,若查找的数比6大,那么6所在的列就不用查找了(它是该列的最大),反之,若查找的数比6小,该行也不用查找了,这样也可以整行整列的跳过。
综上,起始点选择副对角线的左下和右上都是可行的,中间的对角元素存在二义性,不可取。
bool Find(vector<vector<int> > &matrix, int number){
int rows = matrix.size();
if(rows == 0) return false;
int cols = matrix[0].size();
int search_row = 0;
int search_col = cols - 1;
while (search_row < rows && search_col >= 0)
{
int cur_num = matrix[search_row][search_col]
if(cur_num == number)
return true;
else if(cur_num < number)
search_row++;
else
search_col--;
}
return false;
}