劍指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.

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