牛客链接:二维数组的查找
暴力方法是遍历两边,复杂度是O(mn)。
核心是二分查找。
二分法:O(nlogm)。
bool Find(int target, vector<vector<int> >& array) {
// write code here
for(auto &row : array){
int l = 0;
int r = row.size() - 1;
while(l <= r){
int mid = l + r >> 1;
if(target == row[mid]){
return true;
}else if(target < row[mid]){
r = mid - 1;
}else{
l = mid + 1;
}
}
}
return false;
}
另外方法:复杂度更低O(n+m)。从右上到左下遍历。这样的思路是因为,从右上到左下,要想变大就只能row++,想变小就只能col–。
bool Find(int target, vector<vector<int> >& array) {
// write code here
//右上角逼近左下角
int row = 0;
int col = array[0].size() - 1;
while(row < array.size() && col >=0){
if(target == array[row][col]) return true;
if(target < array[row][col]) col--;
else row++;
}
return false;
}
另:关注c++模式的写法:相比传统的索引ij写法,c++11风格的写法有更多的好处。
- 更简洁,更抽象,可读性更强,不需要管理索引,管理索引可能导致越界。
- 性能更优秀,&是引用传递,避免了一些不必要的拷贝操作。
for(auto &row : array) {
for(auto &element : row) {
if(target == element) return true;
}
}