剑指Offer 二维数组中的查找
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
题目分析
题目中明确描述数组从左至右从上至下都是递增的顺序,所以一眼就能看出来这是个二分查找的问题,只不过是一个二维的二分查找问题。
做这个题目有三种思路(示意图中的数字为查找次数,表格代表数组,横线代表查找方向):
- 行和列分开查找
- 行和列同时查找(i,j每次从0开始)
可以看到每个元素都被重复查找了(当数据量比较大时,很浪费时间)
这样的方式比较方便写代码。 - 行和列同时查找(不重复查找元素)
只有横竖两条线交界处才会重复。
代码展示
// 二分查找
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int low, high = array.size() - 1, RowMid;
int left, right = array[0].size() - 1, ListMid;
int bound = high > right ? right : high ;
int i = 0;
while(i <= bound){
low = left = i; /*这里要格外注意*/
while((low <= high) || (left <= right)){
if(low <= high){
RowMid = (low + high) / 2;
if(array[RowMid][i] == target)
return true;
else if(target > array[RowMid][i])
low = RowMid + 1;
else
high = RowMid - 1;
}
if(left <= right){
ListMid = (left + right) / 2;
if(array[i][ListMid] == target)
return true;
else if(target > array[i][ListMid])
left = ListMid + 1;
else
right = ListMid - 1;
}
}
i++;
}
return false;
}
};
int main()
{
int n = 4, m = 5, temp;
vector< vector<int> > array;
vector<int> v;
bool result;
Solution solution;
array.clear();
for(int i = 0; i < n; i++){
v.clear();
for(int j = 0; j < m; j++){
cin >> temp;
v.push_back(temp);
}
array.push_back(v);
}
result = solution.Find(13,array);
cout << result;
return 0;
}
/*
1 2 3 4 5
3 6 7 8 9
4 10 11 12 13
7 15 16 17 18
*/
代码在牛客网已通过(提交时只需要Find函数中的内容)