一、題目:二維數組中的查找
題目:在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
例如下面的二維數組就是每行、每列都遞增排序。如果在這個數組中查找數字7,則返回true;如果查找數字5,由於數組不含有該數字,則返回false。
二、解題思路
首先選取數組中右上角的數字。如果該數字等於要查找的數字,查找過程結束;如果該數字大於要查找的數字,剔除這個數字所在的列;如果該數字小於要查找的數字,剔除這個數字所在的行。也就是說如果要查找的數字不在數組的右上角,則每一次都在數組的查找范圍中剔除一行或者一列,這樣每一步都可以縮小查找的范圍,直到找到要查找的數字,或者查找范圍為空。
例如,我們要在上述的二維數組中查找數字7的步驟如下圖所示:
(矩陣中加陰影背景的區域是下一步查找的范圍)
三、解決問題
3.1 代碼實現
// 二維數組matrix中,每一行都從左到右遞增排序, // 每一列都從上到下遞增排序 public static bool Find(int[,] matrix, int rows, int columns, int number) { bool isFind = false; if (matrix != null && rows > 0 && columns > 0) { // 從第一行開始 int row = 0; // 從最后一列開始 int column = columns - 1; // 行:從上到下,列:從右到左 while (row < rows && column >= 0) { if (matrix[row, column] == number) { isFind = true; break; } else if (matrix[row, column] > number) { column--; } else { row++; } } } return isFind; }
在前面的分析中,我們每一次都是選取數組查找范圍內的右上角數字。同樣,我們也可以選取左下角的數字。但我們不能選擇左上角或者右下角。以左上角為例,最初數字1位於初始數組的左上角,由於1小於7,那么7應該位於1的右邊或者下邊。此時我們既不能從查找范圍內剔除1所在的行,也不能剔除1所在的列,這樣我們就無法縮小查找的范圍。
3.2 單元測試
(1)要查找的數字在數組中
[TestMethod] public void FindTest1() { // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的數在數組中 int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; // 可以通過GetLength()方法獲取行數和列數 //Assert.AreEqual(Program.Find(matrix, matrix.GetLength(0), matrix.GetLength(1), 7), true); Assert.AreEqual(Program.Find(matrix, 4, 4, 7), true); }
(2)要查找的數不在數組中
[TestMethod] public void FindTest2() { // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的數不在數組中 int[,] matrix = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}}; Assert.AreEqual(Program.Find(matrix, 4, 4, 5), false); }
(3)要查找的數是數組中最小的數字
[TestMethod] public void FindTest3() { // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的數是數組中最小的數字 int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; Assert.AreEqual(Program.Find(matrix, 4, 4, 1), true); }
(4)要查找的數是數組中最大的數字
[TestMethod] public void FindTest4() { // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的數是數組中最大的數字 int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; Assert.AreEqual(Program.Find(matrix, 4, 4, 15), true); }
(5)要查找的數比數組中最小的數字還小
[TestMethod] public void FindTest5() { // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的數比數組中最小的數字還小 int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; Assert.AreEqual(Program.Find(matrix, 4, 4, 0), false); }
(6)要查找的數比數組中最大的數字還大
[TestMethod] public void FindTest6() { // 1 2 8 9 // 2 4 9 12 // 4 7 10 13 // 6 8 11 15 // 要查找的數比數組中最大的數字還大 int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } }; Assert.AreEqual(Program.Find(matrix, 4, 4, 16), false); }
(7)魯棒性測試,輸入空指針
[TestMethod] public void FindTest7() { // 魯棒性測試,輸入空指針 Assert.AreEqual(Program.Find(null, 0, 0, 16), false); }
單元測試結果: