有序二维数组查找的两种方法:从左上角(递归)和右上角(非递归)出发

有序二维数组查找

这道题是在学习剑指offer这本书看到的,原题如下所示:
  在一个二维数组中,每行都按照从左到右递增的顺序排序,每列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

分块治之

在拿到题目的时候,我并没有找到右上角那么优秀的特征,所以我选择二分查找的有序数组的思想,最初的想法是从最小值(左上角)到最大值(右下角)进行扇形搜索。
在这里插入图片描述
例如上边的这个数组,但是发现该数组并不具备这样的条件,因为扇形搜索的话,同半径下的元素,例如9,9,7,6这四个元素并不相等,但是发现一个有趣的规律,假如我沿着该矩阵左上角最大最小值这样的对角线,针对7这个元素进行搜索,搜索到绿色区域10这个元素时,绿色部分均大于等于10,进而大于7,而黄色部分均小于7,这样便可以将黄,绿两个区域进行排除,只搜索蓝色区域即可,同时针对蓝色区域同样执行一样的搜索模式,这样的话便可以分块递归处理了。同时为了处理不对称情况作出了以下处理:

  1. 只针对矩阵中从左上角出发最大的正形矩阵进行搜索,剩下的矩阵(粉红区域)下一步搜索
  2. 对于当前搜索矩阵,当在对角线搜索到目标值时,返回当前搜索区域已搜索到目标值
  3. 当前搜索矩阵左上角第一个元素大于目标值时,返回当前搜索区域无目标值
  4. 当前搜索矩阵右下角第一个元素小于目标值时,返回当前搜索区域无目标值
  5. 当前搜索矩阵对角线中部存在大于目标值元素时,搜索进一步该元素的蓝色区域

学过数据结构与算法的同学一样就可以看出这个算法的弊端,当这个二维数组退化为一维数组时,本算法的时间复杂度也会退化成O(n)O(n)O(n)。不过作为脑海中的第一种实现方法,我还是打算把它记录下来。代码如下 :

template <typename item>
bool _FindInPartiallySortedMatrixTopLeft(item *array, item value, int startx, int starty, int endx, int endy,
                                         int column) {
   
   
    assert(startx <= endx && starty <= endy);
    int currentrow = endx - startx;
    int currentcolumn = endy - starty;
    int count = currentrow < currentcolumn ? currentrow : currentcolumn;
//            std::cout << startx << "," \
//                     << starty << "-->"\
//                     << endx << ","\
//                     << endy << "\n";
    item currentItem = 0;
    int currentX = startx;
    int currentY = starty;
    for (int i = 0; i <= count; ++i, ++currentX, ++currentY) {
   
   
        currentItem = array[currentX * column + currentY];
        if (currentItem == value) {
   
   
            return true;
        } else if (currentItem > value
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlameAlpha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值