笔试面试一直被算法题搞死,现在刷题虽然晚了点,但还是刷一刷吧.........
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
arr = [
[1, 2, 3, 4, 5, 6],
[2, 3, 4, 5, 6, 7],
[3, 4, 5, 6, 7, 8]
]
题解:
1. 暴力法
从上到下、从左到右遍历,不赘述,复杂度O(n^2)
2. 二分法
因为不能保证下一行的第一个数比上一行的最后一个数大,所以针对全局的二分法不可取,如果只是针对每一行进行二分查找的话是可以的,复杂度O(nlogn)
3. 从左下角往右上角搜寻,或者反过来
从左下角开始,如果target比当前的值大的话,说明当前列以及左边的所有都比target小,所以右移一个位置,如果target比当前的值大的话,说明当前行以及下边的所有都比target大,所以上移一个位置
代码实现:
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int rows = array.size();
if(rows == 0) return false;
int cols = array[0].size();
if(cols == 0) return false;
// 上面判断两种特殊情况
int col = 0;
int row = rows - 1;
// 从左下角开始找
while(col < cols && row >= 0) {
if(array[row][col] == target) return true;
if(array[row][col] > target) row--;
else if(array[row][col] < target) col++;
}
return false;
}
};