题目描述:
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数
示例:
现有矩阵 matrix 如下:
[
[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
。
限制:
0 <= n <= 1000
0 <= m <= 1000
1、二维数组中的查找
方法一:遍历
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
for(int i=0;i<array.size();i++)//第几行
{
for(int j=0;j<array[0].size();j++)//第几列
{
if(array[i][j] == target)
return true;
}
}
return false;
}
};
方法二、
数组从左到右和从上到下都是递增顺序,因此可考虑对角线上的元素一定是左上角范围内的最大值。假设对角线第i个元素为,对角线上比target小的元素的最大值,对角线上第j个元素为,对角线上比target大的元素的最小值。将查找范围缩小[(i, i), (j, j)]构成的正方形中。
踩坑
未考虑到边界条件,即数组为空的情况。
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
if(array.empty() || array[0].empty())//考虑到边界条件,即数组为空的情况
return false;
int i = 0,j = array[0].size()-1;
while(i<=array.size() - 1 && j>=0)
{
if(array[i][j] == target) return true;
if(array[i][j] > target) j--;
else i++;
}
return false;
}
};
方法三、二分法
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.empty() || matrix[0].empty())//矩阵为空,或者二维数组第一行为空,返回flase
return false;
int x = matrix.size();//有多少行
int y = matrix[0].size();//每一行长度
for(int i = 0; i < x; i++)//遍历每一行
{
if(target >= matrix[i][0] && target <= matrix[i][y-1])
{
//进行二分查找--模板
int l = 0; int r = y - 1;
while(l < r)
{
int mid = (l + r) >> 1;//二分
if(matrix[i][mid] > target)
{
r = mid;
}
else
{
l = mid + 1;
}
}
if(matrix[i][l] == target)
return true;
}
else if (target < matrix[i][0])//在对每一行的第一个数判断
break;
}
return false;
}
};