题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字 7,则返回 true;如果查找数字 5, 由于数组不含有该数字,则返回false。 1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15
解法一:遍历整个二维数组
这种思路演变为二维数组的遍历,由于内外两个 for 循环,因此时间复杂度为 O(N*N);
代码如下:
1 #include <iostream> 2 using namespace std; 3 4 bool find(int *matrix, int rows, int cols, int num) 5 { 6 if(matrix == NULL || rows <= 0 || cols <= 0 7 || num < matrix[0] || num > matrix[rows*cols-1]) 8 return false; 9 10 for(int i = 0; i < rows; ++i) 11 { 12 for(int j = 0; j < cols; ++j) 13 { 14 if(num == matrix[i*cols+j]) 15 return true; 16 } 17 } 18 return false; 19 } 20 21 int main(int argc, char *argv[]) 22 { 23 int arr[4][4] = {1, 2, 8, 9, 2, 4, 9, 12, 4, 7, 10, 13, 6, 8, 11, 15}; 24 bool isFind = find((int*)arr, 4, 4, 7); 25 cout << "isFind: " << isFind << endl; 26 return 0; 27 }
解法二:利用该二维数组的特性
思路:我们选择数组最右上角的数字与num比较;
列:假设该 num 为 7,由于 9 > 7,因此根据数组列元素的递增规律,最右列的所有元素都大于 7,所以我们可以把最右列从需要考虑的区域内剔除(变量 col-- 即可);
行:假设该 num 为 10,由于 9 < 10,因此根据数组行元素的递增规律,第一行的所有元素都小于 10,所以我们可以把第一行从需要考虑的区域内剔除(变量 row++ 即可)。
以下为 num 为 7 时所查找的过程:
注:矩阵中加阴影背景的区域是下一个要查找的范围
把整个查找过程分析清楚之后,我们不难写出如下代码:
1 // findNum.cpp 2 #include <iostream> 3 using namespace std; 4 5 bool find(int *matrix, int rows, int cols, int num) 6 { 7 if(matrix == NULL || rows <= 0 || cols <= 0 8 || num < matrix[0] || num > matrix[rows*cols-1]) 9 return false; 10 11 int row = 0, col = cols-1; 12 while(row < rows && col >= 0) 13 { 14 if(matrix[row*cols+col] == num) 15 return true; 16 else if(matrix[row*cols+col] > num) 17 col--; 18 else 19 row++; 20 } 21 22 return false; 23 } 24 25 int main(int argc, char *argv[]) 26 { 27 int arr[4][4] = {1, 2, 8, 9, 2, 4, 9, 12, 4, 7, 10, 13, 6, 8, 11, 15}; 28 29 for(int i = 0; i < 20; ++i) 30 { 31 bool isFind = find((int*)arr, 4, 4, i); 32 cout << i << " isFind: " << isFind << endl; 33 } 34 return 0; 35 }
注:while结束的条件为当行变量 row(从0开始)等于或大于给出的总行数rows;或者列变量col(从 cols-1开始)小于0时,循环结束。
编译与执行:
1 g++ -o findNum findNum.cpp 2 ./findNum
性能分析:
从以上代码可知每循环一次,我们都会减掉一列或者一行,直到找到该num为止,因此时间复杂度为O(N)。
本文完。