题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如,数组为
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
如果在数组中查找数字9,则返回true;如果查找数字20,则返回false。
思路:元素是分别按行按列递增,但是每一行(列)的元素不一定都比前一行(列)元素大。因此,我们要利用元素的排列特点,按照一定的规律去寻找元素。
由于已经知道每一列是从上到下递增排序,我们先选左下角的第一个元素,即第一列的最大值,作为起始元素(记为p=a[row][col])比较元素;
当待寻找元素num>p时,说明第一列不含该元素(p已是该列最大值),因此p要按行递增(col++);
若num<p,说明最后一行不含该元素,因此p要按列递减(row--);
若num == p,则返回true。这样做的目的就是,每一步缩小搜索的范围(矩形)。
误区:当看到元素是按行按列递增时,可能第一反应是左对角的二分搜索,而这种情况会发现有重叠,判断条件过多容易导致思维混乱。
code:
1 bool Find(int *matrix, int rows, int columns, int num) 2 { 3 bool Found = false; 4 if (matrix == NULL || rows <= 0 || columns <= 0) 5 { 6 return Found; 7 } 8 //起始元素为矩阵左下角元素 9 int nRow = rows - 1; 10 int nCol = 0; 11 12 while (nRow >= 0 && nCol < columns) 13 { 14 if (matrix[nRow * columns + nCol] == num) 15 { 16 Found = true; 17 } 18 if (matrix[nRow * columns + nCol] < num) 19 { 20 ++nCol; 21 } 22 else 23 { 24 --nRow; 25 } 26 } 27 return Found; 28 }
ps:《剑指OFFER》上的起始元素是按右上角选取。