剑指Offer:二维数组中的查找(两种解法)
-
问题描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例: vector<vector > 【1, 2, 8, 9 】
【2, 4, 9, 12】
【4, 7, 10,13】
【6, 11, 15,16】
2. 解题思路
解法1:利用二分查找以及该二维数组的特性
在示例中查询 6 ,执行的原理为:
①:先在第一行执行二分查找,
②:得到所需要查询的数介于vector[0][1]、vector[0][2]之间
③:接着查询第二行,但是第二行不做全部二分查找,由于所查询的数比vector[0][2],
所以所查询的数在vector[1][0]和vector[1][2]之间,以此减少运算,以下以此类推
解法2:利用该二维数组的特性
在示例中查询6,执行的步骤原理为:
①:首先我们需要确定一个以前,类似于走矩阵,此点的约束是:左下角或者右上角
原因:因为选择左下角或者右上角作为起点出发的话,可以根据该二维数组特性:拿右上角为例
如果查找的数比当前点小,则向左移动一个单位
如果查找的数比当前点大,则想下移动一个单位
②:从[9出发(6<9) 向左] -> [8(6<8) 向左] -> [2(6>2) 向下] -> [4(6>4)向下] -> [7(6<7)向左] -> [4(6>4)向下] -> [6]
③:直到向左,或者是向下超出范围,查找完毕。这种情况即时查找不到
④:最坏的情况就是,从(左下角->右上角)或者是(右上角->左下角)。时间复杂度最长,为o(m+n)
3.c++源码
解法1:
bool half_Find(int target, vector<vector<int> > array)
{
if(array.empty())
{
return false;
}else
{
if(array[0].empty())
{
return false;
}
}
int len = array[0].size();
int left = 0;
int right = array[0].size() - 1;
int index = 0;
for(int i = 0;i < array.size();i++)
{
while(1)
{
index = (left + right)/2;
if(target == array[i][index])
{
return true;
}
else if(target > array[i][index])
{
if(index == right)
{
left = index;
right = len -1;
break;
}
left = index + 1;
}
else if(target < array[i][index])
{
if(index == left)
{
right = index;
left = 0;
break;
}
right = index -1;
}
}
}
return false;
}
解法2
bool Find(int target, vector<vector<int> > array)
{
if(array.empty())
{
return false;
}else
{
if(array[0].empty())
{
return false;
}
}
int index_y_max = array.size() - 1;
int index_x_min = 0;
int index_x = array[0].size() - 1;
int index_y = 0;
while(index_x >= index_x_min && index_y <=index_y_max)
{
if(target == array[index_y][index_x])
{
return true;
}
if(target > array[index_y][index_x])
{
index_y++;
continue;
}
else if(target < array[index_y][index_x])
{
index_x--;
continue;
}
}
return false;
}```
**4. 留言**
CSDN:https://blog.csdn.net/qq_42714490
欢迎交流:
## 作者:有梦想的阿长
## 微信:hs835844948
【转载文章务必保留出处和署名,谢谢!】
来源:CSDN
作者:有梦想的阿长
链接:https://blog.csdn.net/qq_42714490/article/details/104697603