二维数组中的查找 剑指Offer面试题

二维数组中的查找

在一个二维数组中,每一行数字都按照从左到右的顺序递增,每一列数字都按照从上到下的顺序递增,请完成一个函数,判断该数组是否含有某个数字?
例如在下面的数组查找7返回true,查找5返回false。

这里写图片描述

讲真,刚开始看到这道题我第一反应就是顺序遍历一遍查找,但是发现没有用到数字递增的条件,所以肯定不能这么做。想了一会儿没有什么思路就看书了,书上给出的方法是:
取右上角的元素,例如上图的9,如果查找的元素key比9大,去掉9所在的行,元素下移到12。如果查找的元素key比9小,则去掉9所在的列,元素左移到8。如果查找的元素key等于9直接返回true。依次这样下去直到没有元素了与key相等,返回false。
在这里,我们以查找key = 7为例,详细给出查找的过程。

这里写图片描述

有了上面的基础之后,代码就不难了,我自己的代码如下:

bool CanFind(int *a, int rows, int cols, int key)
{
    int i = 0; 
    int j = cols - 1;//初始位置在右上角
    while (i <= rows - 1 && j >= 0)
    {
        if (key < a[i * cols + j])
            --j;//删除该列
        else if (key > a[i * cols + j])
            ++i;//删除该行
        else
            return true;
    }
    return false;
}

写完我对照了书上的代码,发现自己有几点不足:
1. 如果是传入的参数不是合法的,比如a == nullptr的情况处理
2. 如果rows,cols是0甚至是负数的情况处理

修改过后的代码如下:

bool CanFind(int *a, int rows, int cols, int key)
{
    if (a == nullptr || rows <= 0 || cols <= 0)//不合法的输入
        return false;
    int i = 0; 
    int j = cols - 1;//初始位置在右上角
    while (i <= rows - 1 && j >= 0)
    {
        if (key < a[i * cols + j])
            --j;//删除该列
        else if (key > a[i * cols + j])
            ++i;//删除该行
        else
            return true;
    }
    return false;
}

在前面的分析中,我们选择右上角元素,其实左下角元素比如6也可以。但是其他两边左上角右下角则是不行的,比如左上角元素1,查找7的时候,由于7比1大必然在右边或者下边,但是我们却不能剔除1所在的行,也不能能剔除1所在的列这样起不到缩小范围的作用了。

这里写图片描述

PS:完整的代码以及各种情况的测试可点击剑指Offer习题解析之3_FindInPartiallySortedMatrix查看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值