剑指offer面试题3:在二维数组中查找数字

题目:给定一个二维整型数组和一个数字,查找该数字是否在二维数组中。该二维数组的特点是:每一行的数字递增排序,每一列的数字也是递增排序。

解题方案:
方案1:从数组中间开始查找;
若要查找的数字比中间数字大,则可能出现地方在该数字的右半部分和下半部分,出现重叠;若要查找的数字比中间数字小,则可能出现的地方在该数字的左半部分和上班部分,依旧会重叠。
方案2:从数组左上角或者右下角开始查找;
如果要查找的数字比左上角的数字大,则可能出现的地方会是其他任意位置,同样如果要查找的数字比右下角的数字下,则可能出现的地方会是其他任意位置。
方案3:从数组右上角或者左下角开始查找。
如果该数字比右上角的数字小,则可以剔除该列;如果比右上角的数字大,则可以剔除该行,这样每次查找都能缩小一行或者一列,减小查找的范围。同样从左下角开始查找也是一样,如果比左下角的数字大,则可以剔除该列;如果比左下角的数字小,则可以剔除该行。

所以选择方案3,可以提高查找的效率。

代码实现:

#include <iostream>

using namespace std;

//方法1:从右上角开始查找,如果等于要查找的数字,则停止查找。否则,如果要查找的数字比该数字小,则剔除该列;如果要查找的数字比该数字大,则剔除改行。
bool Find1(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;
}

//方法2:从左下角开始查找,如果该数字等于左下角的数字,则查找过程结束。否则,如果该数字大于左下角的数字,则剔除该列;如果该数字小于左下角的数字,则剔除改行。
bool Find2(int* matrix, int rows, int columns, int number)
{
    bool found = false;
    if (matrix != NULL && rows > 0 && columns > 0)
    {
        int row = rows - 1;
        int column = 0;
        while (row >= 0 && column < columns)
        {
            if (matrix[row * columns + column] == number)
            {
                found = true;
                break;
            }
            else if (matrix[row * columns + column] > number)
            {
                --row;
            }
            else
            {
                ++column;
            }
        }
    }
    return found;
}

//测试
void test(char* testName, int* matrix, int rows, int columns, int number, bool expected)
{
    if (testName != NULL)
    {
        cout << testName << endl;
    }
    //  bool result = Find1(matrix, rows, columns, number);
    bool result = Find2(matrix, rows, columns, number);
    if (result == expected)
    {
        cout << "Passed." << endl;
    }
    else
    {
        cout << "Failed." << endl;
    }
}

//该数字在二维数组中
void test1()
{
    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 test2()
{
    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, 7, true);
}

//该数字是二维数组的最小值
void test3()
{
    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 test4()
{
    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 test5()
{
    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 test6()
{
    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, 15, false);
}

//检查代码的鲁棒性
void test7()
{
    int matrix[][4] = {
        { 1,2,8,9 },
        { 2,4,9,12 },
        { 4,7,10,13 },
        { 6,8,11,15 }
    };
    test("test7", NULL, 0, 0, 9, false);
}

int main(int argc, char* argv[])
{
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    test7();

    return 0;
}

测试结果:
test1
Passed.
test2
Passed.
test3
Passed.
test4
Passed.
test5
Passed.
test6
Failed.
test7
Passed.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章