在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
若没有要求限制,那么可以遍历整个二维数组;最坏的情况就是找n*m 次,此时时间复杂度为O(n*m),时间复杂度较高;
既然遍历二维数组不能满足题目的要求,那么就需要借助数组非递减的性质来完成题目。
在非递减数组中,右上角的元素是比较特殊的,它是所在行的最大值,所在列的最小值;
那么从它下手无疑是最好的:
假如查找的数字k=7;就可以这样找:
1.与右上角的元素进行比较,如果k大于右上角的元素,行数+1;
如果k小于右上角的元素,列数-1;
2.行和列是不能一直+或者-下去的,所以有一个限定条件:行<=row-1;列>=0;(若找不到则不存在)
行数+1可以排除一行,列数-1可以排除一列,时间复杂度O(n+m);
代码:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.size() == 0) {
return false;
}
int row = matrix.size(), col = matrix[0].size();
int x = 0, y = col - 1;
while(x < row && y >= 0) {
if(matrix[x][y] > target) {
y--;
}
else if(matrix[x][y] < target) {
x++;
}
else {
return true;
}
}
return false;
}