剑指Offer - 九度1384 - 二维数组中的查找
2013-11-23 23:23
- 题目描述:
-
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
- 输入:
-
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的矩阵的行数和列数。
输入的第二行包括一个整数t(1<=t<=1000000):代表要查找的数字。
接下来的m行,每行有n个数,代表题目所给出的m行n列的矩阵(矩阵如题目描述所示,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
- 输出:
-
对应每个测试案例,
输出”Yes”代表在二维数组中找到了数字t。
输出”No”代表在二维数组中没有找到数字t。
- 样例输入:
-
3 3 5 1 2 3 4 5 6 7 8 9 3 3 1 2 3 4 5 6 7 8 9 10 3 3 12 2 3 4 5 6 7 8 9 10
- 样例输出:
-
Yes No No
题意分析:
在一个有序的二维数组中查找某一元素。很容易发现此二维数组从左往右、从上往下都是递增的,因此可以直接展开成一个一维数组,a[i][j] = a[i * col + j],row为行数,col为列数。
接下来,就是标准的二分查找了。时间复杂度O(log(m * n)),空间复杂度O(1)。
1 // 650233 zhuli19901106 1384 Accepted 点击此处查看所有case的执行结果 4968KB 813B 690MS 2 // 201311121726 3 #include <cstdio> 4 using namespace std; 5 6 const int MAXN = 1005; 7 int a[MAXN][MAXN]; 8 int x, y; 9 10 int main() 11 { 12 int i, j; 13 int left, right, mid; 14 int target; 15 16 while(scanf("%d%d", &x, &y) == 2){ 17 scanf("%d", &target); 18 for(i = 0; i < x; ++i){ 19 for(j = 0; j < y; ++j){ 20 scanf("%d", &a[i][j]); 21 } 22 } 23 if(x * y <= 0){ 24 printf("No\n"); 25 continue; 26 } 27 left = 0; 28 right = x * y - 1; 29 while(left <= right){ 30 mid = (left + right) / 2; 31 i = mid / y; 32 j = mid % y; 33 if(target < a[i][j]){ 34 right = mid - 1; 35 }else if(target > a[i][j]){ 36 left = mid + 1; 37 }else{ 38 break; 39 } 40 } 41 42 printf((left <= right) ? "Yes\n" : "No\n"); 43 } 44 45 return 0; 46 }