題目:給定一個二維整型數組和一個數字,查找該數字是否在二維數組中。該二維數組的特點是:每一行的數字遞增排序,每一列的數字也是遞增排序。
解題方案:
方案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.