2014-03-21 21:50
题目:给定一个MxN的二位数组,如果每一行每一列都是升序排列(不代表全展开成一个一维数组仍是升序排列的)。请设计一个算法在其中查找元素。
解法:对于这么一个数组,有两点是确定的:1. 左上最小,右下最大;2. 左边不大于右边,上边不大于下边。根据这么个思路,你可以从左下或者右上开始查找,应该向左走向右走,还是向上走向下走,你懂的。用这种方法,可以在线性的时间内找出一个元素。
代码:
1 // 11.6 Given an MxN matrix, each row and each column is sorted in ascending order. 2 // For emxample, 3 // [10 19] 4 // [15 21] 5 // It doesn't mean you can expand it to a one dimensional array and still sorted. 6 #include <cstdio> 7 #include <vector> 8 using namespace std; 9 10 void searchMatrix(vector<vector<int> > &v, int target, int &rx, int &ry) 11 { 12 int n, m; 13 14 rx = ry = -1; 15 n = (int)v.size(); 16 if (n == 0) { 17 return; 18 } 19 m = (int)v[0].size(); 20 21 int i, j; 22 23 i = 0; 24 j = m - 1; 25 while (i <= n - 1 && j >= 0) { 26 if (target > v[i][j]) { 27 ++i; 28 } else if (target < v[i][j]) { 29 --j; 30 } else { 31 rx = i; 32 ry = j; 33 return; 34 } 35 } 36 return; 37 } 38 39 int main() 40 { 41 vector<vector<int> > v; 42 int n, m; 43 int i, j; 44 int target; 45 46 while (scanf("%d%d", &n, &m) == 2 && n > 0 && m > 0) { 47 v.resize(n); 48 for (i = 0; i < n; ++i) { 49 v[i].resize(m); 50 } 51 for (i = 0; i < n; ++i) { 52 for (j = 0; j < m; ++j) { 53 scanf("%d", &v[i][j]); 54 } 55 } 56 while (scanf("%d", &target) == 1) { 57 searchMatrix(v, target, i, j); 58 printf("(%d, %d) ", i, j); 59 } 60 for (i = 0; i < n; ++i) { 61 v[i].clear(); 62 } 63 v.clear(); 64 } 65 66 return 0; 67 }