題目
在一個二維數組中,每一行都是按照從左到右遞增的順序排序,每一列都是按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
解題思想
選取數組中右上角的數字。
(1)如果該數字等於要查找的數字,查找過程結束;
(2)如果該數字大於要查找的數字,剔除這個數字所在的列;
(3)如果該數字小於要查找的數字,剔除這個數字所在的行
也就是說如果要查找的數字不在數組的右上角,則每一次都在數組的查找範圍中剔除一行或者一列,這樣每一步都可以縮小查找的範圍,直到找到要查找的數字,或者查找範圍爲空。
測試用例&代碼
(1)二維數組中包含查找的數字(查找的數字是數組中的最大值和最小值,查找的數字介於數組中的最大值和最小值之間)
(2)二維數組中沒有查找的數字(查找的數字大於數組中的最大值,查找的數字小於數組中的最小值,查找的數字在數組的最大值和最小值之間,但數組中沒有這個數字)
(3)特殊輸入測試(輸入空指針)
// FindInPartiallySortedMatrix.cpp : Defines the entry point for the console application.
//
// 《劍指Offer——名企面試官精講典型編程題》代碼
// 著作權所有者:何海濤
#include "stdafx.h"
// 二維數組matrix中,每一行都從左到右遞增排序,
// 每一列都從上到下遞增排序
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(char* testName, int* matrix, int rows, int columns, int number, bool expected)
{
if(testName != NULL)
printf("%s begins: ", testName);
bool result = Find(matrix, rows, columns, number);
if(result == expected)
printf("Passed.\n");
else
printf("Failed.\n");
}
// 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的數在數組中
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);
}
// 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的數不在數組中
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, 5, false);
}
// 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的數是數組中最小的數字
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);
}
// 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的數是數組中最大的數字
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);
}
// 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的數比數組中最小的數字還小
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);
}
// 1 2 8 9
// 2 4 9 12
// 4 7 10 13
// 6 8 11 15
// 要查找的數比數組中最大的數字還大
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, 16, false);
}
// 魯棒性測試,輸入空指針
void Test7()
{
Test("Test7", NULL, 0, 0, 16, false);
}
int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
return 0;
}
本題考點
(1)對二維數組的理解及編程能力。二維數組在內存中佔據連續的空間。在內存中從上到下存儲各行元素,在同一行中按照從左到右的順序存儲。因此我們可以根據行號和列號計算出相對於數組首地址的偏移量,從而找到對應的元素
(2)分析問題的能力。當應聘者發現問題比較複雜時,能不能通過具體的例子找出其中的規律,是能否解決這個問題的關鍵所在。這個題目只要從一個具體的二維數組的右上角開始分析,就能找到查找的規律,從而找到解決問題的突破口。