题目描述:
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:
首先遍历行,如果发现查找目标不在本行值域内,就移动到下一行。如果发现目标值在本行的值域内,则依次将本行的每一个元素与查找目标比对。相信和大多数的菜鸟思路一样。但是写完之后总感觉这种方法太蠢,果然看了大佬的代码茅塞顿开。
代码:
bool Find(int target,vector<vector<int> > array){
if(array.empty() || array[0].empty()) return false;
int len1 = array.size();
int len2 = array[0].size();
for(int i = 0; i < len1; i++){
if(target < array[i].front() || target > array[i].back()) continue;
for(int j = 0; j < len2; j++){
if(target == array[i][j]) return true;
}
}
return false;
}
改进:
定义row和col指向变量,row指向第一行,col指向最后一列,也就是我们选择的初始比对位置在整个数组的右上角,初始位置这样选择我们一会就能看到这样选择的好处。
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
假设我们要查找的数字为7
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7<15,显然15这一列的元素全都大于15,那么这一列的元素也全都大于4,这一列可以全部排除,将col前移一位
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7<10,继续将col前移
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7<8:
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
再次比对我们发现7>5,因为本行中前面的元素都比5小,所以可以将本行的元素全部排除,row下移,到下一行寻找目标值:
1 | 5 | 8 | 10 | 15 |
2 | 7 | 9 | 11 | 22 |
4 | 10 | 20 | 30 | 40 |
7 == 7,成功找到了这个值!
这种方法,每一次比对都能排除一整行或者一整列的数据,大大节约了时间。
代码:
if(array.empty() || array[0].empty()) return false;
int row = 0;
int col = array[0].size() - 1;
int rowLen = array.size();
while(col >= 0 && row < rowLen){
if(array[row][col] == target) return true;
else if(target > array[row][col]) row++;
else col--;
}
return false;