题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
以下为 2019.6.5 更新
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
/**
* 二维数组中的查找,直接暴力匹配。总能找到 target
*/
#if 0
if(array.empty())
{
return false;
}
int rows = static_cast<int>(array.size());
int cols = static_cast<int>(array[0].size());
for(int i = 0; i < rows; ++i)
{
cols = static_cast<int>(array[i].size());
for(int j = 0; j < cols; ++j)
{
if (array[i][j] == target)
{
return true;
}
}
}
return false;
#endif
/*
* 但是很明显这种方法的时间复杂度为O(n^2) 未免有点太高了
* 再次观察题目,我们发现这个二维数组很有规律,
* 从左往右递增,从上递增
* 考虑到这样的规律,我们可以考虑优化本题
* 我们选取当前数组最右上角的元素,然后比较,
* 如果 array[row][col] > target,那么这一列的元素都可以排除掉,
* 因为数组从上到下递增,下面的元素必定都比 array[row][col] 大,
* 所以不可能在这一列找到 target, 我们 --col 这样就排除一列的搜索
* 如果 array[row][col] < target,那么这一行的元素都可以被剔除,
* 道理与上面一样
*/
if (array.empty())
{
return false;
}
int rows = static_cast<int>(array.size());
int cols = static_cast<int>(array[0].size());
int row = 0; //
int col = cols - 1;
while(row < rows && col >= 0)
{
if(array[row][col] == target)
{
return true;
}
else if(array[row][col] > target)
{
--col;
}
else
{
++row;
}
}
return false;
}
};
以上为 2019.6.5 更新
- 题解:
拿到这个题,第一种思路就是遍历一遍
这是一个时间复杂度为 O(n2) 的办法
代码如下:
代码已上传gitbub,可用 git 工具下载查看
github 代码链接,欢迎查看
#include <iostream>
#include <vector>
class Solution {
public:
bool Find(int target, std::vector<std::vector<int> > array) {
for(size_t i = 0; i < array.size(); ++i)
{
for(size_t j = 0; j < array[i].size(); ++j)
{
if(array[i][j] == target)
{
return true;
}
}
}
return false;
}
};
可以通过oj,但是仔细阅读题目发现没有充分利用题目的条件,我们再来阅读一遍题目:
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
我们就可以利用这个条件,
- 我们把二维数组想象成一个矩阵的形式
- 那么会有三种情况:
- 当数组中选取的数字刚好等于目标值,结束查找过程
- 如果选取的数字小于目标值,则目标值可能出现在当前位置的右边或者下边
- 如果选取的数字大于目标值,则目标值可能出现在==当前位置的左边或者上边
- 这样做,就会不断缩小我们的查找范围
比如现在我们的数组是这样的:
int array[4][4] = {
1, 2, 8, 9,
2, 4, 9, 12,
4, 7, 10, 13,
6, 8, 11, 15
};
我们要来查找 7 这个元素
9大于7,下一次只能在9的左边区域查找
8大于7,下一次只能在8的左边区域查找
2小于7,下一次只能在2的下边区域查找
这次就找到7了。
所以我们可以考虑把刚刚的代码优化:
class Solution {
public:
bool Find(int target, std::vector<std::vector<int> > array)
{
// 先参数检验
int rows = (int)array.size(); // 这里强转的原因是 array.size()的返回值类型为 size_t
if(rows == 0)
{
return false;
}
int cols = (int)array[0].size();
if(cols == 0)
{
return false;
}
int row = 0;
int col = cols - 1;
while(row < rows && col >= 0)
{
if(array[row][col] == target)
{
return true;
}
else if(array[row][col] > target)
{
--col;
}
else
{
++row;
}
}
return false;
}
};
这份代码也通过了oj ,而且比第一种更加优化。
如果你还有别的思路欢迎留言探讨 ?