一刷剑指offer笔记(3)——二维数组中的查找

数组,占据一块连续内存并按照顺序存储数据的一种最简单的数据结构。

数组的空间效率不好,经常会有空闲的区域没有得到充分利用。

数组的时间效率较好,可以根据下标在O(1)时间读写任何元素。

可以利用数组来实现简单哈希表O(1)查找:以数组下标作为哈希表的键值key,以数组中的每一个数字作为哈希表的值(value).

值得注意的是,当数组作为函数的参数进行传递时,数组会自动退化为同类型的指针。

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

最直接的思路,把二维数组画成矩形,然后从数组中选取一个数字,分3种情况考虑。

当数组选取的数字==要查找的数字,结束查找;

当数组选取的数字<要查找的数字,继续查找当前选取位置的右边或者下边;

当数组选取的数字>要查找的数字,继续查找当前选取位置的上边或者左边。

通过上面的分析,如果要查找的数字相对于当前选取的位置有可能在两个区域中出现,而且这两个区域还有重叠,问题就很复杂。

复杂的原因在于貌似越往下找,就陷得越深,我们需要找到一种方法,能够一边找,一边尽可能地筛出较多的不满足的数据。

思考一下,该题一直在强调一种关系:严格的大小关系。

如果能够把尽可能多的数字按顺序排好,那么是不是就可以实现每一次查找筛除比它小或比它大的数据。

可以发现这样一个顺序排列:

是不是很明显,我们可以从右上角入手!

如果该数字等于要查找的数字,查找结束;

如果该数字大于要查找的数字,剔除这个数字所在列;

如果该数字小于要查找的数字,剔除这个数字所在行

bool Find(int* matrix,int rows,int columns,int number)
{
    bool found=false;
    if(matrix!=NULL && rows>0 && columns>0)
    {
        int row=0;
        int column=columns-1;
        while(row<rows && column>=0)
        {
            if(matrix[row*columns+column]==number)
            {
                found=true;
                break;
            }
            else if(matrix[row*columns+column]>number)
                --column;
            else
                ++row;
        }
     }
    return found;
}

同理,也可以选择左下角的数字,只要满足顺序排列即可。

但是不可选择左上角或者右下角!否则无法缩小查找范围。

下面贴出完整的代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
bool Find(int* matrix,int rows,int columns,int number)
{
    bool found=false;
    if(matrix!=NULL && rows>0 && columns>0)
    {
        int row=0;
        int column=columns-1;
        while(row<rows && column>=0)
        {
            if(matrix[row*columns+column]==number)
            {
                found=true;
                break;
            }
            else if(matrix[row*columns+column]>number)
                --column;
            else
                ++row;
        }
    }
    return found;
}

void test(string testname,int* matrix,int rows,int columns,int number,bool expected)
{
    if(testname!="")
        cout<<testname<<" begins:";
    bool result=Find(matrix,rows,columns,number);
    if(result==expected)
        cout<<"pass!"<<endl;
    else
        cout<<"failed!"<<endl;
}

void test_1()
{
     int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
     test("Test1", (int*)matrix, 4, 4, 7, true);
}

void test_2()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    test("Test2", (int*)matrix, 4, 4, 5, false);
}

void test_3()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    test("Test3", (int*)matrix, 4, 4, 1, true);
}

void test_4()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    test("Test4", (int*)matrix, 4, 4, 15, true);
}

void test_5()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    test("Test5", (int*)matrix, 4, 4, 0, false);
}

void test_6()
{
    int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
    test("Test6", (int*)matrix, 4, 4, 16, false);
}

void test_7()
{
    test("Test7",NULL, 0, 0, 16, false);
}

int main()
{
    test_1();
    test_2();
    test_3();
    test_4();
    test_5();
    test_6();
    test_7();

    return 0;
}

在codeblocks 17.0下的测试结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值