二维数组中的查找----newcoder

题目描述

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

newcoder 题目链接


以下为 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 ,而且比第一种更加优化。


如果你还有别的思路欢迎留言探讨 ?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值