剑指offer------004(二维数组中查找整数)

更多题目请点链接:《剑指offer》目录索引

问题描述:

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

分析问题:

从问题描述中,可以确定一下几点:

1)在二维数组中查找整数,根据学过的知识可知,二维数组可看做一维数组,故此题可在一维数组中求解
2)此数组的特点是从左到右递增排序,从上到下递增排序;故有几个特殊的位置需要注意:左上角,右上角,左下角,右下角;这几个位置便是解题的突破点
3)左上角和右下角分别是数组中最小和最大的整数,右上角元素为当前列最小,所在行最大,左下角则相反

解题思路:

由上述题目的分析,我们可任意选取4个特殊位置其中一个开始查找;例如从左下角开始查找:左下角为当前行(row)最小,当前列(col)大元素(a),如果待查找元素(key)小于 a, 去 row-1 行查找,如果待查找元素(key)大于 a,去 col+1 列查找(下面附图)

》查找4

这里写图片描述

》查找11

这里写图片描述

》查找7

这里写图片描述

具体代码:


int Find(int  **arr, int key)
{
    assert(*arr);//防止数组为空

    int row = 4-1;//左下角
    int col = 0;
    while (row >=0 && col < 4)
    {
        if (arr[row][col] == key)
        {
            return 1;//如果找到,返回1
        }
        else if (arr[row][col]<key)
        {
            ++col;//如果当前元素小于待查找元素,在col+1列找
        }
        else
        {
            --row;//如果当前元素大于待查找元素,在row-1行找
        }
    }
    return -1;
}

进阶:一维数组实现上面函数

int YangFind1(int *arr, int row, int col, int key)
{

    if(arr == NULL)
       return -1;

    if (  row >= 0 && col >= 0)
    {
        int  i = 0;//控制行
        int  j = col - 1;//控制列

        while (i < row&& j >= 0)
        {
            if (arr[i*col + j] == key)
            {
                return i*col + j;//找到返回下标
            }
            else  if (key>arr[i*col + j])
            {
                ++i;
            }
            else
            {
                --j;
            }
        }
    }

    return -1;
}

分析:根据前面分析问题可知,二维数组可看做一维数组,故可将一维数组转化为二维数组进行求解,此时需注意下标的控制(附图)

这里写图片描述

测试用例:

注意:测试用例设计时,要做到全面,不能遗漏;查找时,最小值,最大值,不在数组中的值以及数组是空数组

1)二维数组实现

void Test()
{

    int  arr[ROW][COL] = {
                                { 1, 2, 8, 9 },
                                { 2, 4, 9, 12 },
                                { 4, 7, 10, 13 },
                                { 6, 8, 11, 15 },
                            };



    printf("%d \n", Find(arr, 1));
    printf("%d \n", Find(arr,  7));
    printf("%d \n", Find(arr,  10));
    printf("%d \n", Find(arr,  13));
    printf("%d \n", Find(arr,  15));
    printf("%d \n", Find(arr,  0));
    printf("%d \n", Find(NULL, 0));

}

2)一维数组实现

void Test1()
{
    int a[] = { 1, 2, 8, 9, 2, 4, 9, 12, 4, 7, 10, 13, 6, 8, 11, 15 };
    printf("%d \n", YangFind1(a, 4, 4, 1));
    printf("%d \n", YangFind1(a, 4, 4, 7));
    printf("%d \n", YangFind1(a, 4, 4, 15));
    printf("%d \n", YangFind1(NULL, 4, 4, 0));
}

结果:

这里写图片描述

这里写图片描述

说明:第一张图显示结果断言失败,因为在最后传了空指针NULL过去,所以发生报错

    assert(*arr);//防止数组为空

第二张图有两个-1,这里也是传了一个空指针,但处理时将NULL当成数组的一种状态,如果是空,则返回-1

if(arr == NULL)
       return -1;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值